Long series
plot(long, type='l')

spec.pgram(long, detrend = TRUE, fast = FALSE, log='no', taper=0)

Предполагем, что достаточно сгруппировать 8 компонент, т.к. возможно, ранг равен 8 (линейный тренд + 3 косинуса).
Как выбирать L
Так как точной разделимости в реальных рядах не бывает, нас интересует асимтотическая разделимость.
В большинстве случаев скорость асимптотической разделимиости пропорциональна \(1/\min(L, K)\), \(K = N - L + 1\), поэтому выбираем \(L\) близкое к \(N/2\).
Если мы хотим отделять косинус с некоторым периодом, то для улучшения разделимости рекомендуется брать окно кратное периоду (следует из условий точной слабой разделимости).
Слабая и сильная разделимость
- Слабая разделимость – ортогональность траекторных подпространств
- Сильная азделимость – слабая разделимость + в разных компонентах (SVD) разные собственные числа
Decomposition
ssa.long <- ssa(long, kind='1d-ssa')
Собственные числа:
\(\lambda_i = \|\mathbf{X}_i\|^2_{\mathcal{F}}\), \(\lambda_i/ \|\mathbf{X}\|^2_{\mathcal{F}}\) – вклад компоненты
plot(ssa.long)

Как идентифицировать тренд?
Хотим выделить все элементарные компоненты, которые имеют медленно меняющиеся собственные вектора.
Собственные ветора образуют базис траекторного подпространства, следовательно, они имеют вид соответствующих компонент ряда.
Собственные вектора:
plot(ssa.long, type='vectors', idx = 1:15)

Первые два – линейный тренд, дальше идут периодические компоненты.
Как идентифицировать периодичность
Посмотрим на скаттерплоты пар собственных векторов.
- Знаем, что экспоненциально модулированный косинус соответствует двум собственным тройкам с примерно одинаковыми собственными числами (\(Lw\) – целые). Отсюда следует, что эти SVD компоненты скорее всего идут друг за другом
- Эти две периодические компоненты (собственные вектора), отличаются на \(\pi/2\) по фазе (при целых \(Lw\)).
Таким образом, видимые Т-угольники соответствуют периодическим компонентам с периодом Т.
plot(ssa.long, type='paired', idx= c(1:20))

Заметны компоненты с периодами 20, 10 и 6. Есть компонента, похожая на период 2.4, компонента похожая на период ~6.
Элементарные восстановленные компоненты
plot(ssa.long, type='series', groups = list(1:2, 3:4, 5:6, 7:8, 9:10, 11:12))

Оценка параметров (ESPRIT)
\(x_n = \sum\limits_{j = 1}^r C_j \mu_j^n + \epsilon_n\) – ряд, \(\mu_j = \rho_je^{2\pi i \omega_j}\) – корни х.п.
Алгоритм ESPRIT-LS:
- Применив SSA и получив SVD разложение, составляем r собственных векторов в матрицу \(\mathbb{U}\)
- \(\widehat{\mathbb{D}} = \underline{\mathbb{U}}^-\bar{\mathbb{U}}\)
- Собственные чилса – оценки сигнальных корней
parestimate(ssa.long, groups = list(1:12), method = "esprit-ls")
period rate | Mod Arg | Re Im
10.008 0.000360 | 1.00036 0.63 | 0.80960 0.58760
-10.008 0.000360 | 1.00036 -0.63 | 0.80960 -0.58760
20.006 0.000299 | 1.00030 0.31 | 0.95137 0.30903
-20.006 0.000299 | 1.00030 -0.31 | 0.95137 -0.30903
Inf 0.000104 | 1.00010 0.00 | 1.00010 0.00000
Inf -0.000109 | 0.99989 0.00 | 0.99989 0.00000
5.999 -0.000352 | 0.99965 1.05 | 0.49963 0.86583
-5.999 -0.000352 | 0.99965 -1.05 | 0.49963 -0.86583
2.217 -0.000564 | 0.99944 2.83 | -0.95263 0.30227
-2.217 -0.000564 | 0.99944 -2.83 | -0.95263 -0.30227
6.665 -0.001292 | 0.99871 0.94 | 0.58685 0.80810
-6.665 -0.001292 | 0.99871 -0.94 | 0.58685 -0.80810
Компоненты смешались. Как понять, это слабая или сильная разделимость?
Нет слабой разделимости – отсутствие ортогональности траекторных подпространств.
- Посмотреть на матрицу взвешенных корреляций \(\rho_{ij}(X_N^{(i)},X_N^{(j)}) = \frac{(X^{(i)}_N, X^{(j)}_N)_w}{\|X^{(i)}_N\|_w\|X^{(j)}_N\|_w}\).
По такой матрице поймем, хорошо ли мы разделили компоненты. Поймем, какие компоненты делить не стоит.
- Можно посмотреть на частотные коэффициенты корреляции (достаточное условие слабой отделимости)
W-корреляционная матрица
plot(wcor(ssa.long, groups = as.list(1:15)))

Матрица практически диагональная – тренды и сезонные компоненты практически w-ортогональны
Нет сильной разделимости – одинаковые собственные числа оказались в разных компонентах
- Можно посмотреть на вклады компонент, ступеньки будут соответствовать близким собственным числам
Reconstruction
В предположении, что ранг ряда 8, получим
long.reconstructed <- reconstruct(ssa.long, list(
trend = c(1, 2),
periodic = 3:8))
res.long <- residuals(long.reconstructed)
par(mfrow=c(4,1))
plot(long, type = 'l')
plot(long.reconstructed$trend, type='l', ylab = "trend")
plot(long.reconstructed$periodic, type='l', ylab = "periodic")
plot(res.long, type='l')

Автоковариационная функция
acf(res.long, lag.max = 50)

Шум похож на белый.
Корни ХП
Min-norm ЛРФ
- \(P_i\) – столбцы траекторной матрицы
- \(\underline{P}_{i}\) – вектор \(P_i\) без последней координаты
- \(\pi_i\) – последняя координата \(P_i\)
Коэффициенты min-norm ЛРФ:
\(\mathcal{R} = \frac{1}{1-\nu^2}\sum\limits_{i=1}^{d}{\pi_i \underline{P}_{i}}\), где \(\nu^2 = \pi_1^2 + … + \pi_d^2\)
\(x_{i + d} = \sum\limits_{k = 1}^da_kx_{i + d - k}\), \(a_d \neq 0\) – минимальная ЛРФ
\(P(\mu) = \mu^d - \sum\limits_{k = 1}^da_k\mu^{d - k}\) – характеристический полином ЛРФ
\(\{\mu_j\}_{j = 1}^p\) – корни х.п. кратности \(k_j\), \(\sum k_j = d\), тогда
\(x_n = \sum\limits_{m = 1}^p(\sum\limits_{j = 0}^{km - 1} C_{m_j} n^j)\mu_m^n\)
min-norm ЛРФ и ее корни (предполагаем, что ранг ряда 8)
lr <- lrr(ssa.long, groups = list(1:8))
plot(lr)

r <- roots(lr)
Хотим построить формулу для сигнала ряда с шумом.
Взяв большое окно и построив min-norm ЛРФ, найдем много корней х.п.
Как выбрать из них те r корней, что определяют структуру сигнала?
Найдем сигнальные корни, воспользовавшись утверждением, что у min-norm ЛРФ все лишние корни по модулю меньше единицы.
mods <- Mod(r)
print(r[mods >= 1])
[1] 0.8098255+0.5875445i 0.8098255-0.5875445i 0.9513031+0.3091901i 0.9513031-0.3091901i 1.0000664+0.0000000i
Перевернем ряд
lr.back <- lrr(ssa.long, groups = list(1:8), reverse = TRUE)
r.back <- roots(lr.back)
mods.back <- Mod(r.back)
print(r.back[mods.back >= 1])
[1] 1.000001+0i
Модули главных корней
main.roots <- c(r[Mod(r) >= 1], 1/r.back[Mod(r.back) >= 1])
print(Mod(main.roots))
[1] 1.0005128 1.0005128 1.0002881 1.0002881 1.0000664 0.9999993
Соответствующие периоды
print(2*pi/Arg(main.roots))
[1] 10.01067 -10.01067 19.99437 -19.99437 Inf Inf
plot(main.roots, xlim = c(-1,1), ylim = c(-1,1), asp = 1, xlab = "Re", ylab = "Im")
draw.circle(0,0,1,border = 'red')

Нашлось только 6 сигнальных корней, а должно быть 8.
Попробуем другой способ:
Составим систему и найдем коэффициенты по МНК
complex.LS <- function(series, series.roots){
X <- mapply(FUN = function(root){root^(1:length(series))}, series.roots)
Y <- cbind(series)
list(coef = solve(Conj(t(X))%*%X) %*% Conj(t(X)) %*% Y,
X = X)
}
coeffs.estimates <- complex.LS(long.reconstructed$trend + long.reconstructed$periodic, r)
Воспользуемся тем, что перед сигнальными корнями должны стоять максимальные коэффициенты
idx.roots <-order(Mod(coeffs.estimates$coef), decreasing = TRUE)[1:8]
main.roots<-r[idx.roots]
res.coeffs <- coeffs.estimates$coef[idx.roots]
Модули главных корней
print(Mod(main.roots))
[1] 0.9999324 1.0000664 0.6414650 1.0002881 1.0002881 0.9865705 0.9865705 0.9874613
Соответствующие периоды
print(2*pi/Arg(main.roots))
[1] Inf Inf Inf -19.99437 19.99437 13.87755 -13.87755 13.58822
plot(main.roots, xlim = c(-1,1), ylim = c(-1,1), asp = 1, xlab = "Re", ylab = "Im")
draw.circle(0,0,1,border = 'red')

relation <- function(n){
rbind(res.coeffs) %*% t(mapply(FUN = function(root){root^n}, main.roots))
}
plot(long.reconstructed$trend + long.reconstructed$periodic, type = 'l', ylab = "series")
lines(x = 1:1000, y = Re(relation(1:1000)), col = 'red')

Short series
plot(short, type='l')

spec.pgram(short, detrend = TRUE, fast = FALSE, log='no', taper=0, xaxt = 'n')
l <- seq(0, 0.5, 0.05)
axis(1, at = l, labels = l)

Ожидаем, что ранг ряда как минимум 4 (тренд + синус).
Decomposition
short.ssa <- ssa(short, kind='1d-ssa')
Собственные числа
plot(short.ssa)

Собственные вектора:
plot(short.ssa, type='vectors', idx = 1:20)

plot(short.ssa, type='paired', idx= c(1:20))

parestimate(short.ssa, groups = list(3:4, 5:6, 7:8, 11:12, 13:14))
$F1
period rate | Mod Arg | Re Im
17.587 0.000000 | 1.00000 0.36 | 0.93686 0.34971
$F2
period rate | Mod Arg | Re Im
5.151 0.000000 | 1.00000 1.22 | 0.34386 0.93902
$F3
period rate | Mod Arg | Re Im
6.265 0.000000 | 1.00000 1.00 | 0.53780 0.84307
$F4
period rate | Mod Arg | Re Im
3.133 0.000000 | 1.00000 2.01 | -0.42103 0.90705
$F5
period rate | Mod Arg | Re Im
2.363 -0.000000 | 1.00000 2.66 | -0.88605 0.46360
plot(wcor(short.ssa, groups = as.list(1:20)))

short.reconstructed <- reconstruct(short.ssa, list(
trend = c(1, 2),
periodic = c(3:8,11:14)))
res.short <- residuals(short.reconstructed)
par(mfrow=c(4,1))
plot(short, type = 'l')
plot(short.reconstructed$trend, type='l', ylab = "trend")
plot(short.reconstructed$periodic, type='l', ylab = "periodic")
plot(res.short, type='l')

acf(res.short, lag.max = 50)

Projection SSA
Двойное центрирование
\(\mathcal{A}(\mathbf{X}) = [\mathcal{E}_1(\mathbf{X}) : \ldots : \mathcal{E}_1(\mathbf{X})]\), где \(\mathcal{E}_1(\mathbf{X})\) – вектор из средних по строкам
\(\mathcal{B}(\mathbf{X}) = [\mathcal{E}_{12}(\mathbf{X}) : \ldots : \mathcal{E}_{12}(\mathbf{X})]\), где \(\mathcal{E}_{12}(\mathbf{X})\) – вектор, в котором j-ая компонента равна среднему компонент \(X_j^{(c)} = X_i - \mathcal{E}_1(\mathbf{X})\).
При двойном центрировании применяем SVD к матрице \(\mathbf{A} = \mathcal{A}(\mathbf{X}) + \mathcal{B}(\mathbf{X})\)
Получим разложение \(\mathbf{X} = \mathbf{A} + \sum\limits_{i = 1}^d\sqrt{\lambda_i}U_iV_i^\mathrm{T}\), где \((\lambda_i, U_i, V_i)\) соответствуют \(S^* = (\mathbf{X} - \mathbf{A})(\mathbf{X} - \mathbf{A})^\mathrm{T}\).
Так как исходный тренд линейный, двойное центрирование поможет отделить линейную часть от колебаний (линейная часть попадет в \(\mathbf{A}\)).
short.projection.ssa <- ssa(x = short, column.projector = 'centering', row.projector = 'centering')
plot(short.projection.ssa)

plot(short.projection.ssa, type='vectors', idx = 1:20)

По виду собственных векторов видно, что тренд отделился лучше.
plot(short.projection.ssa, type='paired', idx= c(1:20))

parestimate(short.projection.ssa, groups = list(3:4, 5:6, 7:8, 11:12, 13:14), method ="esprit-ls")
$F1
period rate | Mod Arg | Re Im
19.760 -0.003204 | 0.99680 0.32 | 0.94683 0.31165
-19.760 -0.003204 | 0.99680 -0.32 | 0.94683 -0.31165
$F2
period rate | Mod Arg | Re Im
5.332 -0.021225 | 0.97900 1.18 | 0.37444 0.90456
-5.332 -0.021225 | 0.97900 -1.18 | 0.37444 -0.90456
$F3
period rate | Mod Arg | Re Im
6.238 -0.037821 | 0.96289 1.01 | 0.51434 0.81400
-6.238 -0.037821 | 0.96289 -1.01 | 0.51434 -0.81400
$F4
period rate | Mod Arg | Re Im
3.194 -0.016631 | 0.98351 1.97 | -0.37971 0.90725
-3.194 -0.016631 | 0.98351 -1.97 | -0.37971 -0.90725
$F5
period rate | Mod Arg | Re Im
2.359 -0.067364 | 0.93485 2.66 | -0.83013 0.42993
-2.359 -0.067364 | 0.93485 -2.66 | -0.83013 -0.42993
short.reconstructed <- reconstruct(short.projection.ssa, list(
trend = c(1, 2),
periodic = c(3:8,11:14)))
res.projection <- residuals(short.reconstructed)
par(mfrow=c(4,1))
plot(short, type = 'l')
plot(short.reconstructed$trend, type='l', ylab = "trend")
plot(short.reconstructed$periodic, type='l', ylab = "periodic")
plot(res.projection, type='l')

acf(res.projection, lag.max = 50)

Стало немного лучше, но все-таки что-то осталось.
Последовательный анализ реального ряда
uk <- read.csv("UK.csv", sep = ',', stringsAsFactors = FALSE)
uk <- ts(uk$EXPEND, start = c(1980, 1), frequency = 12)
df.uk <- data.frame(seq.Date(from = as.Date("1980-01-01"), to = as.Date("2016-12-01"), by = "month"), uk)
colnames(df.uk) <- c("DATE", "EXP")
head(uk, 24)
Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
1980 117 116 166 180 202 290 298 441 388 260 175 105
1981 137 142 176 231 240 316 363 537 487 324 185 133
plot(uk)

Периодограмма ряда
spec.pgram(uk, detrend = TRUE, fast = FALSE, log='no', xaxt = 'n')
axis(1, at = c(0,1,2,3,4,5,6), labels = c('0', '1/12', '2/12', '3/12', '4/12', '5/12', '6/12'))

Сглаживание
- Тренд сложной формы, возможно, не описывается рядом конечной размерности
- Если выберем большое окно, компоненты тренда смешаются с периодическими
- Возьмем маленькое окно: хорошо выделим тренд, но смешаются остальные компоненты
- Решение: сначала выделим тренд с маленьким окном, потом применим SSA с большим окном к остатку.
Выбираем небольшую длину окна кратную периоду сезонной компоненты, L = 24.
uk.ssa <- ssa(uk, L = 24)
Вклады
plot(uk.ssa)

Видно, что собственные числа периодических компонент близкие. Скорее всего эти компоненты смешаются (проблема с сильной разделимостью).
Собственные вектора
plot(uk.ssa, type="vectors", idx=1:12)

plot(uk.ssa, type="paired", idx=1:11)

Восстановленные по элементарным компонентам
plot(uk.ssa, type ='series', groups = as.list(1:12))

Первая элементарная компонента соответствует тренду, дальше идут периодики.
Выделение тренда
uk.trend <- reconstruct(uk.ssa, groups = list(1))
plot(uk)
lines(uk.trend$F1, col = 'red')

uk.detrended <- residuals(uk.trend)
Периодограмма остатка
spec.pgram(uk.detrended, detrend = FALSE, fast = FALSE, log='no', xaxt = 'n')
axis(1, at = c(0,1,2,3,4,5,6), labels = c('0', '1/12', '2/12', '3/12', '4/12', '5/12', '6/12'))

Ожидаем, что дальше будет достаточно выделить 9 компонент (синус с периодом 2 имеет ранг 1).
Сезонность
Возьмем максимальное \(L \leq N/2\) кратное 12, т.е. 216 (длина ряда 444).
uk.detrended.ssa <- ssa(uk.detrended, L=216)
plot(uk.detrended.ssa)

Видно ступеньки, которые, возможно, соответствуют синусоидам.
plot(uk.detrended.ssa, type = "paired", idx = 1:30, plot.contrib = FALSE)

Заметны компоненты, соответствующие периодам 12, 6, 4 и 2.4.
Компонента, соответствующая периоду 2.
plot(uk.detrended.ssa, type = "vectors", idx = 9, plot.contrib = FALSE)

Проверим
parestimate(uk.detrended.ssa, groups = list(1:9), method = "esprit-ls")
period rate | Mod Arg | Re Im
3.995 0.005162 | 1.00518 1.57 | -0.00196 1.00517
-3.995 0.005162 | 1.00518 -1.57 | -0.00196 -1.00517
11.991 0.004041 | 1.00405 0.52 | 0.86934 0.50236
-11.991 0.004041 | 1.00405 -0.52 | 0.86934 -0.50236
2.000 0.003889 | 1.00390 3.14 | -1.00390 0.00000
5.995 0.003856 | 1.00386 1.05 | 0.50114 0.86983
-5.995 0.003856 | 1.00386 -1.05 | 0.50114 -0.86983
2.401 0.003558 | 1.00356 2.62 | -0.86881 0.50231
-2.401 0.003558 | 1.00356 -2.62 | -0.86881 -0.50231
W-корреляционная матрица
plot(wcor(uk.detrended.ssa, groups = as.list(1:20)))

uk.seasonality <- reconstruct(uk.detrended.ssa, groups = list(1:9))
res1 <- residuals(uk.seasonality)
par(mfrow=c(4,1))
plot(uk, type = 'l', ylab='Original')
plot(uk.trend$F1, type='l', ylab='Trend')
plot(uk.seasonality$F1, type='l', ylab = 'Seasonal Component')
plot(res1, type='l', ylab='Residuals')

В остатке остался тренд.
acf(res1)

spec.pgram(res1, detrend = FALSE, fast = FALSE, log='no', xaxt = 'n')
axis(1, at = c(0,1,2,3,4,5,6), labels = c('0', '1/12', '2/12', '3/12', '4/12', '5/12', '6/12'))

Оценка дисперсии шума
sigma.n.sqr <- ssa(res1^2, L = 30)
sigma.n <- sqrt(reconstruct(sigma.n.sqr, groups = list(1))$F1)
plot(res1, type='l')
lines(sigma.n, type = 'l', col='blue')
lines(-sigma.n, type='l', col='blue')

2D-SSA для разложения изображения
Рассмотрим фотографию спутника Сатурна, Дионы (Источник).
Прочитали картинку
dione <- readJPEG("Dione.jpg")
image(dione, col = grey(seq(0, 1, length = 256)))

Добавим шум
set.seed(100)
noise.matrix <- apply(dione, 2, function(x){rnorm(length(x), sd = 0.3)})
dione.noised <- dione + noise.matrix
image(dione.noised, col = grey(seq(0, 1, length = 256)))

2d-ssa
dione.ssa <- ssa(dione.noised, kind = "2d-ssa", L = c(25,25))
Собственные вектора
plot(dione.ssa, type = "vectors", idx = 1:30, cuts = 255, layout = c(10, 2), plot.contrib = FALSE)


w-корреляционная матрица
plot(wcor(dione.ssa, groups = 1:30),scales = list(at = seq(10, 30, 5)))

Сгруппируем компоненты с частотами похожего вида
dione.reconstructed <- reconstruct(dione.ssa, groups = list(I1 = c(1:13), I2 = c(14:15), I3 = c(16:17)))
Накопленные суммы компонент
plot(dione.reconstructed, cuts = 255, layout = c(5, 1), par.strip.text = list(cex = 0.75), type = "cumsum", at = "free")

Shaped SSA
Уберем черный фон
dione.without.black <- apply(dione, 2, FUN = function(col){
sapply(col, FUN = function(element){
if(element <= 0.1){
return(NA)
} else{
return(element)
}
})
})
image(dione.without.black, col = grey(seq(0, 1, length = 256)))

Добавим шум
dione.without.black.noised <- dione.without.black + noise.matrix
image(dione.without.black.noised, col = grey(seq(0, 1, length = 256)))

Попробуем изменить форму окна на круг.
dione.ssa.shaped <- ssa(dione.without.black.noised, kind = "2d-ssa", wmask = circle(20))
Some field elements were not covered by shaped window. 1253 elements will be ommited
plot(dione.ssa.shaped, type = "vectors", idx = 1:30, cuts = 255, layout = c(10, 2), plot.contrib = FALSE)


w-корреляционная матрица
plot(wcor(dione.ssa.shaped, groups = 1:30),scales = list(at = seq(10, 30, 5)))

По матрице можно сделать вывод о том, что приблизительно 10 первых компонент относятся к сигналу, а остальное это шум.
Сгруппируем компоненты с частотами похожего вида
dione.reconstructed.shaped <- reconstruct(dione.ssa.shaped, groups = list(I1 = c(1:6), I2 = c(7:12), I3 = c(13:19)))
Накопленные суммы компонент
plot(dione.reconstructed.shaped, cuts = 255, layout = c(5, 1), par.strip.text = list(cex = 0.75), type = "cumsum", at = "free")

На вид, исходная картинка лучше отделилась от шума в случае shaped SSA.
Exponential Smoothing
(ES vs SSA vs ARIMA)
es.fit <- es(uk.train, h = 72)
Forming the pool of models based on... ANN, ANA, ANM, AAM, Estimation progress: 45%55%64%73%82%91%100%... Done!

MSE
sum((tail(uk,72) - es.fit$forecast)^2)/72
[1] 91021.91
Модель
es.fit$formula
[1] "y[t] = (l[t-1] + b[t-1]) * s[t-12] * e[t]"
uk.trend.forecast <- predict(uk.train.ssa, method = "recurrent", len = 72, groups = 1)
uk.seasonality.forecast <- predict(uk.train.detrended.ssa, method = "recurrent", len = 72, groups = list(1:9))
plot(uk, xlim = c(2010, 2018))
lines(uk.trend.forecast + uk.seasonality.forecast, col = 'red')

sum((tail(uk,72) - (uk.trend.forecast + uk.seasonality.forecast))^2)/72
[1] 117129.6
auto.fit.uk <- auto.arima(uk.train, trace = TRUE, stepwise = FALSE, allowdrift = FALSE)
ARIMA(0,0,0)(0,1,0)[12] : 4609.677
ARIMA(0,0,0)(0,1,1)[12] : 4605.92
ARIMA(0,0,0)(0,1,2)[12] : 4570.102
ARIMA(0,0,0)(1,1,0)[12] : 4613.276
ARIMA(0,0,0)(1,1,1)[12] : Inf
ARIMA(0,0,0)(1,1,2)[12] : Inf
ARIMA(0,0,0)(2,1,0)[12] : 4575.118
ARIMA(0,0,0)(2,1,1)[12] : Inf
ARIMA(0,0,0)(2,1,2)[12] : Inf
ARIMA(0,0,1)(0,1,0)[12] : 4507.381
ARIMA(0,0,1)(0,1,1)[12] : 4508.452
ARIMA(0,0,1)(0,1,2)[12] : 4485.141
ARIMA(0,0,1)(1,1,0)[12] : 4519.165
ARIMA(0,0,1)(1,1,1)[12] : 4513.546
ARIMA(0,0,1)(1,1,2)[12] : Inf
ARIMA(0,0,1)(2,1,0)[12] : 4500.653
ARIMA(0,0,1)(2,1,1)[12] : Inf
ARIMA(0,0,1)(2,1,2)[12] : Inf
ARIMA(0,0,2)(0,1,0)[12] : 4437.354
ARIMA(0,0,2)(0,1,1)[12] : 4430.973
ARIMA(0,0,2)(0,1,2)[12] : 4420.724
ARIMA(0,0,2)(1,1,0)[12] : 4438.837
ARIMA(0,0,2)(1,1,1)[12] : 4436.083
ARIMA(0,0,2)(1,1,2)[12] : Inf
ARIMA(0,0,2)(2,1,0)[12] : 4442.367
ARIMA(0,0,2)(2,1,1)[12] : Inf
ARIMA(0,0,3)(0,1,0)[12] : 4420.287
ARIMA(0,0,3)(0,1,1)[12] : 4405.62
ARIMA(0,0,3)(0,1,2)[12] : 4397.304
ARIMA(0,0,3)(1,1,0)[12] : 4411.34
ARIMA(0,0,3)(1,1,1)[12] : 4411.748
ARIMA(0,0,3)(2,1,0)[12] : 4422.04
ARIMA(0,0,4)(0,1,0)[12] : 4401.569
ARIMA(0,0,4)(0,1,1)[12] : 4382.084
ARIMA(0,0,4)(1,1,0)[12] : 4386.684
ARIMA(0,0,5)(0,1,0)[12] : 4383.458
ARIMA(1,0,0)(0,1,0)[12] : 4407.718
ARIMA(1,0,0)(0,1,1)[12] : 4344.179
ARIMA(1,0,0)(0,1,2)[12] : 4340.676
ARIMA(1,0,0)(1,1,0)[12] : 4357.705
ARIMA(1,0,0)(1,1,1)[12] : 4352.702
ARIMA(1,0,0)(1,1,2)[12] : Inf
ARIMA(1,0,0)(2,1,0)[12] : 4366.902
ARIMA(1,0,0)(2,1,1)[12] : 4366.76
ARIMA(1,0,0)(2,1,2)[12] : 4368.57
ARIMA(1,0,1)(0,1,0)[12] : 4345.68
ARIMA(1,0,1)(0,1,1)[12] : 4280.329
ARIMA(1,0,1)(0,1,2)[12] : 4277.132
ARIMA(1,0,1)(1,1,0)[12] : 4290.246
ARIMA(1,0,1)(1,1,1)[12] : 4288.556
ARIMA(1,0,1)(1,1,2)[12] : Inf
ARIMA(1,0,1)(2,1,0)[12] : 4301.595
ARIMA(1,0,1)(2,1,1)[12] : 4302.477
ARIMA(1,0,2)(0,1,0)[12] : 4346.712
ARIMA(1,0,2)(0,1,1)[12] : 4281.757
ARIMA(1,0,2)(0,1,2)[12] : 4278.092
ARIMA(1,0,2)(1,1,0)[12] : 4291.57
ARIMA(1,0,2)(1,1,1)[12] : 4289.544
ARIMA(1,0,2)(2,1,0)[12] : 4302.708
ARIMA(1,0,3)(0,1,0)[12] : 4348.464
ARIMA(1,0,3)(0,1,1)[12] : 4277.812
ARIMA(1,0,3)(1,1,0)[12] : 4291.172
ARIMA(1,0,4)(0,1,0)[12] : 4346.347
ARIMA(2,0,0)(0,1,0)[12] : 4356.483
ARIMA(2,0,0)(0,1,1)[12] : 4294.508
ARIMA(2,0,0)(0,1,2)[12] : 4293.482
ARIMA(2,0,0)(1,1,0)[12] : 4309.562
ARIMA(2,0,0)(1,1,1)[12] : 4304.906
ARIMA(2,0,0)(1,1,2)[12] : Inf
ARIMA(2,0,0)(2,1,0)[12] : 4318.985
ARIMA(2,0,0)(2,1,1)[12] : 4318.889
ARIMA(2,0,1)(0,1,0)[12] : 4347.574
ARIMA(2,0,1)(0,1,1)[12] : 4282.203
ARIMA(2,0,1)(0,1,2)[12] : 4278.389
ARIMA(2,0,1)(1,1,0)[12] : 4292.378
ARIMA(2,0,1)(1,1,1)[12] : 4289.94
ARIMA(2,0,1)(2,1,0)[12] : 4303.347
ARIMA(2,0,2)(0,1,0)[12] : 4347.527
ARIMA(2,0,2)(0,1,1)[12] : 4284.437
ARIMA(2,0,2)(1,1,0)[12] : 4294.897
ARIMA(2,0,3)(0,1,0)[12] : 4349.054
ARIMA(3,0,0)(0,1,0)[12] : 4354.896
ARIMA(3,0,0)(0,1,1)[12] : 4293.657
ARIMA(3,0,0)(0,1,2)[12] : 4291.62
ARIMA(3,0,0)(1,1,0)[12] : 4306.162
ARIMA(3,0,0)(1,1,1)[12] : 4303.185
ARIMA(3,0,0)(2,1,0)[12] : 4316.591
ARIMA(3,0,1)(0,1,0)[12] : 4350.227
ARIMA(3,0,1)(0,1,1)[12] : 4280.178
ARIMA(3,0,1)(1,1,0)[12] : 4293.699
ARIMA(3,0,2)(0,1,0)[12] : 4350.246
ARIMA(4,0,0)(0,1,0)[12] : 4347.801
ARIMA(4,0,0)(0,1,1)[12] : 4286.691
ARIMA(4,0,0)(1,1,0)[12] : 4298.339
ARIMA(4,0,1)(0,1,0)[12] : 4349.489
ARIMA(5,0,0)(0,1,0)[12] : 4350.566
arima.prediction.uk <- predict(auto.fit.uk, 72)
plot(uk, xlim = c(2010, 2018))
lines(arima.prediction.uk$pred, col = 'red')
lines(arima.prediction.uk$pred + arima.prediction.uk$se, lty = 'dashed', col = 'blue')
lines(arima.prediction.uk$pred - arima.prediction.uk$se, lty = 'dashed', col = 'blue')

MSE
sum((tail(uk,72) - arima.prediction.uk$pred)^2)/72
[1] 477969.6
LS0tCnRpdGxlOiAiU1NBIgphdXRob3I6ICLQktC70LDQtNC40LzQuNGAINCQ0LPQtdC10LIiCm91dHB1dDoKICBodG1sX25vdGVib29rOgogICAgdG9jOiB5ZXMKICAgIHRvY19kZXB0aDogMwogICAgdG9jX2Zsb2F0OiB5ZXMKICBodG1sX2RvY3VtZW50OgogICAgdG9jOiB5ZXMKICAgIHRvY19kZXB0aDogJzMnCiAgICB0b2NfZmxvYXQ6IHllcwotLS0KCmBgYHtyLCBlY2hvPUZBTFNFLCBpbmNsdWRlPUZBTFNFfQpsaWJyYXJ5KFJzc2EpCmxpYnJhcnkocGxvdHJpeCkKbGlicmFyeShqcGVnKQpsaWJyYXJ5KHNtb290aCkKYGBgCgoKYGBge3J9CnRhYmxlIDwtIHJlYWQuY3N2Migic3NhLmNzdiIpCmxvbmcgPC0gdGFibGUkQ09MMQpzaG9ydCA8LSBuYS5vbWl0KHRhYmxlJENPTDcpCmBgYAoKI0xvbmcgc2VyaWVzCmBgYHtyfQpwbG90KGxvbmcsIHR5cGU9J2wnKQpgYGAKCmBgYHtyfQpzcGVjLnBncmFtKGxvbmcsIGRldHJlbmQgPSBUUlVFLCBmYXN0ID0gRkFMU0UsIGxvZz0nbm8nLCB0YXBlcj0wKQpgYGAK0J/RgNC10LTQv9C+0LvQsNCz0LXQvCwg0YfRgtC+INC00L7RgdGC0LDRgtC+0YfQvdC+INGB0LPRgNGD0L/Qv9C40YDQvtCy0LDRgtGMIDgg0LrQvtC80L/QvtC90LXQvdGCLCDRgi7Qui4g0LLQvtC30LzQvtC20L3Qviwg0YDQsNC90LMg0YDQsNCy0LXQvSA4ICjQu9C40L3QtdC50L3Ri9C5INGC0YDQtdC90LQgKyAzINC60L7RgdC40L3Rg9GB0LApLgoKCgojI9Ca0LDQuiDQstGL0LHQuNGA0LDRgtGMIEwKCtCi0LDQuiDQutCw0Log0YLQvtGH0L3QvtC5INGA0LDQt9C00LXQu9C40LzQvtGB0YLQuCDQsiDRgNC10LDQu9GM0L3Ri9GFINGA0Y/QtNCw0YUg0L3QtSDQsdGL0LLQsNC10YIsINC90LDRgSDQuNC90YLQtdGA0LXRgdGD0LXRgiDQsNGB0LjQvNGC0L7RgtC40YfQtdGB0LrQsNGPINGA0LDQt9C00LXQu9C40LzQvtGB0YLRjC4KCtCSINCx0L7Qu9GM0YjQuNC90YHRgtCy0LUg0YHQu9GD0YfQsNC10LIg0YHQutC+0YDQvtGB0YLRjCDQsNGB0LjQvNC/0YLQvtGC0LjRh9C10YHQutC+0Lkg0YDQsNC30LTQtdC70LjQvNC40L7RgdGC0Lgg0L/RgNC+0L/QvtGA0YbQuNC+0L3QsNC70YzQvdCwICQxL1xtaW4oTCwgSykkLCAkSyA9IE4gLSBMICsgMSQsINC/0L7RjdGC0L7QvNGDINCy0YvQsdC40YDQsNC10LwgJEwkINCx0LvQuNC30LrQvtC1INC6ICROLzIkLgoK0JXRgdC70Lgg0LzRiyDRhdC+0YLQuNC8INC+0YLQtNC10LvRj9GC0Ywg0LrQvtGB0LjQvdGD0YEg0YEg0L3QtdC60L7RgtC+0YDRi9C8INC/0LXRgNC40L7QtNC+0LwsINGC0L4g0LTQu9GPINGD0LvRg9GH0YjQtdC90LjRjyDRgNCw0LfQtNC10LvQuNC80L7RgdGC0Lgg0YDQtdC60L7QvNC10L3QtNGD0LXRgtGB0Y8g0LHRgNCw0YLRjCDQvtC60L3QviDQutGA0LDRgtC90L7QtSDQv9C10YDQuNC+0LTRgyAo0YHQu9C10LTRg9C10YIg0LjQtyDRg9GB0LvQvtCy0LjQuSDRgtC+0YfQvdC+0Lkg0YHQu9Cw0LHQvtC5INGA0LDQt9C00LXQu9C40LzQvtGB0YLQuCkuCgojI9Ch0LvQsNCx0LDRjyDQuCDRgdC40LvRjNC90LDRjyDRgNCw0LfQtNC10LvQuNC80L7RgdGC0YwKCiog0KHQu9Cw0LHQsNGPINGA0LDQt9C00LXQu9C40LzQvtGB0YLRjCAtLSDQvtGA0YLQvtCz0L7QvdCw0LvRjNC90L7RgdGC0Ywg0YLRgNCw0LXQutGC0L7RgNC90YvRhSDQv9C+0LTQv9GA0L7RgdGC0YDQsNC90YHRgtCyCiog0KHQuNC70YzQvdCw0Y8g0LDQt9C00LXQu9C40LzQvtGB0YLRjCAtLSDRgdC70LDQsdCw0Y8g0YDQsNC30LTQtdC70LjQvNC+0YHRgtGMICsg0LIg0YDQsNC30L3Ri9GFINC60L7QvNC/0L7QvdC10L3RgtCw0YUgKFNWRCkg0YDQsNC30L3Ri9C1INGB0L7QsdGB0YLQstC10L3QvdGL0LUg0YfQuNGB0LvQsAoKRGVjb21wb3NpdGlvbgpgYGB7cn0Kc3NhLmxvbmcgPC0gc3NhKGxvbmcsIGtpbmQ9JzFkLXNzYScpCmBgYArQodC+0LHRgdGC0LLQtdC90L3Ri9C1INGH0LjRgdC70LA6CgokXGxhbWJkYV9pID0gXHxcbWF0aGJme1h9X2lcfF4yX3tcbWF0aGNhbHtGfX0kLCAkXGxhbWJkYV9pLyBcfFxtYXRoYmZ7WH1cfF4yX3tcbWF0aGNhbHtGfX0kIC0tINCy0LrQu9Cw0LQg0LrQvtC80L/QvtC90LXQvdGC0YsKYGBge3J9CnBsb3Qoc3NhLmxvbmcpCmBgYAoKCiMj0JrQsNC6INC40LTQtdC90YLQuNGE0LjRhtC40YDQvtCy0LDRgtGMINGC0YDQtdC90LQ/CgrQpdC+0YLQuNC8INCy0YvQtNC10LvQuNGC0Ywg0LLRgdC1INGN0LvQtdC80LXQvdGC0LDRgNC90YvQtSDQutC+0LzQv9C+0L3QtdC90YLRiywg0LrQvtGC0L7RgNGL0LUg0LjQvNC10Y7RgiDQvNC10LTQu9C10L3QvdC+INC80LXQvdGP0Y7RidC40LXRgdGPINGB0L7QsdGB0YLQstC10L3QvdGL0LUg0LLQtdC60YLQvtGA0LAuCgoK0KHQvtCx0YHRgtCy0LXQvdC90YvQtSDQstC10YLQvtGA0LAg0L7QsdGA0LDQt9GD0Y7RgiDQsdCw0LfQuNGBINGC0YDQsNC10LrRgtC+0YDQvdC+0LPQviDQv9C+0LTQv9GA0L7RgdGC0YDQsNC90YHRgtCy0LAsINGB0LvQtdC00L7QstCw0YLQtdC70YzQvdC+LCDQvtC90Lgg0LjQvNC10Y7RgiDQstC40LQg0YHQvtC+0YLQstC10YLRgdGC0LLRg9GO0YnQuNGFINC60L7QvNC/0L7QvdC10L3RgiDRgNGP0LTQsC4KCtCh0L7QsdGB0YLQstC10L3QvdGL0LUg0LLQtdC60YLQvtGA0LA6CmBgYHtyLCBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9MTB9CnBsb3Qoc3NhLmxvbmcsIHR5cGU9J3ZlY3RvcnMnLCBpZHggPSAxOjE1KQpgYGAK0J/QtdGA0LLRi9C1INC00LLQsCAtLSDQu9C40L3QtdC50L3Ri9C5INGC0YDQtdC90LQsINC00LDQu9GM0YjQtSDQuNC00YPRgiDQv9C10YDQuNC+0LTQuNGH0LXRgdC60LjQtSDQutC+0LzQv9C+0L3QtdC90YLRiy4KCiMj0JrQsNC6INC40LTQtdC90YLQuNGE0LjRhtC40YDQvtCy0LDRgtGMINC/0LXRgNC40L7QtNC40YfQvdC+0YHRgtGMCiAKINCf0L7RgdC80L7RgtGA0LjQvCDQvdCwINGB0LrQsNGC0YLQtdGA0L/Qu9C+0YLRiyDQv9Cw0YAg0YHQvtCx0YHRgtCy0LXQvdC90YvRhSDQstC10LrRgtC+0YDQvtCyLgogCiAqINCX0L3QsNC10LwsINGH0YLQviDRjdC60YHQv9C+0L3QtdC90YbQuNCw0LvRjNC90L4g0LzQvtC00YPQu9C40YDQvtCy0LDQvdC90YvQuSDQutC+0YHQuNC90YPRgSDRgdC+0L7RgtCy0LXRgtGB0YLQstGD0LXRgiDQtNCy0YPQvCDRgdC+0LHRgdGC0LLQtdC90L3Ri9C8INGC0YDQvtC50LrQsNC8INGBINC/0YDQuNC80LXRgNC90L4g0L7QtNC40L3QsNC60L7QstGL0LzQuCDRgdC+0LHRgdGC0LLQtdC90L3Ri9C80Lgg0YfQuNGB0LvQsNC80LggKCRMdyQgLS0g0YbQtdC70YvQtSkuINCe0YLRgdGO0LTQsCDRgdC70LXQtNGD0LXRgiwg0YfRgtC+INGN0YLQuCBTVkQg0LrQvtC80L/QvtC90LXQvdGC0Ysg0YHQutC+0YDQtdC1INCy0YHQtdCz0L4g0LjQtNGD0YIg0LTRgNGD0LMg0LfQsCDQtNGA0YPQs9C+0LwKICog0K3RgtC4INC00LLQtSDQv9C10YDQuNC+0LTQuNGH0LXRgdC60LjQtSDQutC+0LzQv9C+0L3QtdC90YLRiyAo0YHQvtCx0YHRgtCy0LXQvdC90YvQtSDQstC10LrRgtC+0YDQsCksINC+0YLQu9C40YfQsNGO0YLRgdGPINC90LAgJFxwaS8yJCDQv9C+INGE0LDQt9C1ICjQv9GA0Lgg0YbQtdC70YvRhSAkTHckKS4KIAog0KLQsNC60LjQvCDQvtCx0YDQsNC30L7QvCwg0LLQuNC00LjQvNGL0LUg0KIt0YPQs9C+0LvRjNC90LjQutC4INGB0L7QvtGC0LLQtdGC0YHRgtCy0YPRjtGCINC/0LXRgNC40L7QtNC40YfQtdGB0LrQuNC8INC60L7QvNC/0L7QvdC10L3RgtCw0Lwg0YEg0L/QtdGA0LjQvtC00L7QvCDQoi4KCmBgYHtyICwgZmlnLndpZHRoPTEyLCBmaWcuaGVpZ2h0PTEwfQpwbG90KHNzYS5sb25nLCB0eXBlPSdwYWlyZWQnLCBpZHg9IGMoMToyMCkpCmBgYAoK0JfQsNC80LXRgtC90Ysg0LrQvtC80L/QvtC90LXQvdGC0Ysg0YEg0L/QtdGA0LjQvtC00LDQvNC4IDIwLCAxMCDQuCA2LiDQldGB0YLRjCDQutC+0LzQv9C+0L3QtdC90YLQsCwg0L/QvtGF0L7QttCw0Y8g0L3QsCDQv9C10YDQuNC+0LQgMi40LCDQutC+0LzQv9C+0L3QtdC90YLQsCDQv9C+0YXQvtC20LDRjyDQvdCwINC/0LXRgNC40L7QtCB+Ni4gCgojI9Ct0LvQtdC80LXQvdGC0LDRgNC90YvQtSDQstC+0YHRgdGC0LDQvdC+0LLQu9C10L3QvdGL0LUg0LrQvtC80L/QvtC90LXQvdGC0YsKCmBgYHtyfQpwbG90KHNzYS5sb25nLCB0eXBlPSdzZXJpZXMnLCBncm91cHMgPSBsaXN0KDE6MiwgMzo0LCA1OjYsIDc6OCwgOToxMCwgMTE6MTIpKQpgYGAKCiMj0J7RhtC10L3QutCwINC/0LDRgNCw0LzQtdGC0YDQvtCyIChFU1BSSVQpCgokeF9uID0gXHN1bVxsaW1pdHNfe2ogPSAxfV5yIENfaiBcbXVfal5uICsgXGVwc2lsb25fbiQgLS0g0YDRj9C0LCAkXG11X2ogPSBccmhvX2plXnsyXHBpIGkgXG9tZWdhX2p9JCAtLSDQutC+0YDQvdC4INGFLtC/LgoK0JDQu9Cz0L7RgNC40YLQvCBFU1BSSVQtTFM6CgoqINCf0YDQuNC80LXQvdC40LIgU1NBINC4INC/0L7Qu9GD0YfQuNCyIFNWRCDRgNCw0LfQu9C+0LbQtdC90LjQtSwg0YHQvtGB0YLQsNCy0LvRj9C10LwgciDRgdC+0LHRgdGC0LLQtdC90L3Ri9GFINCy0LXQutGC0L7RgNC+0LIg0LIg0LzQsNGC0YDQuNGG0YMgJFxtYXRoYmJ7VX0kCiogJFx3aWRlaGF0e1xtYXRoYmJ7RH19ID0gXHVuZGVybGluZXtcbWF0aGJie1V9fV4tXGJhcntcbWF0aGJie1V9fSQKKiDQodC+0LHRgdGC0LLQtdC90L3Ri9C1INGH0LjQu9GB0LAgXHdpZGVoYXR7XG1hdGhiYntEfX0gLS0g0L7RhtC10L3QutC4INGB0LjQs9C90LDQu9GM0L3Ri9GFINC60L7RgNC90LXQuQoKYGBge3J9CnBhcmVzdGltYXRlKHNzYS5sb25nLCBncm91cHMgPSBsaXN0KDE6MTIpLCBtZXRob2QgPSAiZXNwcml0LWxzIikKYGBgCgoKIyPQmtC+0LzQv9C+0L3QtdC90YLRiyDRgdC80LXRiNCw0LvQuNGB0YwuINCa0LDQuiDQv9C+0L3Rj9GC0YwsINGN0YLQviDRgdC70LDQsdCw0Y8g0LjQu9C4INGB0LjQu9GM0L3QsNGPINGA0LDQt9C00LXQu9C40LzQvtGB0YLRjD8KCtCd0LXRgiDRgdC70LDQsdC+0Lkg0YDQsNC30LTQtdC70LjQvNC+0YHRgtC4IC0tINC+0YLRgdGD0YLRgdGC0LLQuNC1INC+0YDRgtC+0LPQvtC90LDQu9GM0L3QvtGB0YLQuCDRgtGA0LDQtdC60YLQvtGA0L3Ri9GFINC/0L7QtNC/0YDQvtGB0YLRgNCw0L3RgdGC0LIuCgoqINCf0L7RgdC80L7RgtGA0LXRgtGMINC90LAg0LzQsNGC0YDQuNGG0YMg0LLQt9Cy0LXRiNC10L3QvdGL0YUg0LrQvtGA0YDQtdC70Y/RhtC40LkgJFxyaG9fe2lqfShYX05eeyhpKX0sWF9OXnsoail9KSA9IFxmcmFjeyhYXnsoaSl9X04sIFheeyhqKX1fTilfd317XHxYXnsoaSl9X05cfF93XHxYXnsoail9X05cfF93fSQuCgrQn9C+INGC0LDQutC+0Lkg0LzQsNGC0YDQuNGG0LUg0L/QvtC50LzQtdC8LCDRhdC+0YDQvtGI0L4g0LvQuCDQvNGLINGA0LDQt9C00LXQu9C40LvQuCDQutC+0LzQv9C+0L3QtdC90YLRiy4g0J/QvtC50LzQtdC8LCDQutCw0LrQuNC1INC60L7QvNC/0L7QvdC10L3RgtGLINC00LXQu9C40YLRjCDQvdC1INGB0YLQvtC40YIuCgoqINCc0L7QttC90L4g0L/QvtGB0LzQvtGC0YDQtdGC0Ywg0L3QsCDRh9Cw0YHRgtC+0YLQvdGL0LUg0LrQvtGN0YTRhNC40YbQuNC10L3RgtGLINC60L7RgNGA0LXQu9GP0YbQuNC4ICjQtNC+0YHRgtCw0YLQvtGH0L3QvtC1INGD0YHQu9C+0LLQuNC1INGB0LvQsNCx0L7QuSDQvtGC0LTQtdC70LjQvNC+0YHRgtC4KQoKIFct0LrQvtGA0YDQtdC70Y/RhtC40L7QvdC90LDRjyDQvNCw0YLRgNC40YbQsAogCmBgYHtyLCBmaWcud2lkdGg9NSwgZmlnLmhlaWdodD01fQpwbG90KHdjb3Ioc3NhLmxvbmcsIGdyb3VwcyA9IGFzLmxpc3QoMToxNSkpKQpgYGAK0JzQsNGC0YDQuNGG0LAg0L/RgNCw0LrRgtC40YfQtdGB0LrQuCDQtNC40LDQs9C+0L3QsNC70YzQvdCw0Y8gLS0g0YLRgNC10L3QtNGLINC4INGB0LXQt9C+0L3QvdGL0LUg0LrQvtC80L/QvtC90LXQvdGC0Ysg0L/RgNCw0LrRgtC40YfQtdGB0LrQuCB3LdC+0YDRgtC+0LPQvtC90LDQu9GM0L3RiwoK0J3QtdGCINGB0LjQu9GM0L3QvtC5INGA0LDQt9C00LXQu9C40LzQvtGB0YLQuCAtLSDQvtC00LjQvdCw0LrQvtCy0YvQtSDRgdC+0LHRgdGC0LLQtdC90L3Ri9C1INGH0LjRgdC70LAg0L7QutCw0LfQsNC70LjRgdGMINCyINGA0LDQt9C90YvRhSDQutC+0LzQv9C+0L3QtdC90YLQsNGFCgoqINCc0L7QttC90L4g0L/QvtGB0LzQvtGC0YDQtdGC0Ywg0L3QsCDQstC60LvQsNC00Ysg0LrQvtC80L/QvtC90LXQvdGCLCDRgdGC0YPQv9C10L3RjNC60Lgg0LHRg9C00YPRgiDRgdC+0L7RgtCy0LXRgtGB0YLQstC+0LLQsNGC0Ywg0LHQu9C40LfQutC40Lwg0YHQvtCx0YHRgtCy0LXQvdC90YvQvCDRh9C40YHQu9Cw0LwKCgojI1JlY29uc3RydWN0aW9uCgrQkiDQv9GA0LXQtNC/0L7Qu9C+0LbQtdC90LjQuCwg0YfRgtC+INGA0LDQvdCzINGA0Y/QtNCwIDgsINC/0L7Qu9GD0YfQuNC8CmBgYHtyLCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD04fQpsb25nLnJlY29uc3RydWN0ZWQgPC0gcmVjb25zdHJ1Y3Qoc3NhLmxvbmcsIGxpc3QoCiAgdHJlbmQgPSBjKDEsIDIpLAogIHBlcmlvZGljID0gMzo4KSkKcmVzLmxvbmcgPC0gcmVzaWR1YWxzKGxvbmcucmVjb25zdHJ1Y3RlZCkKcGFyKG1mcm93PWMoNCwxKSkKcGxvdChsb25nLCB0eXBlID0gJ2wnKQpwbG90KGxvbmcucmVjb25zdHJ1Y3RlZCR0cmVuZCwgdHlwZT0nbCcsIHlsYWIgPSAidHJlbmQiKQpwbG90KGxvbmcucmVjb25zdHJ1Y3RlZCRwZXJpb2RpYywgdHlwZT0nbCcsIHlsYWIgPSAicGVyaW9kaWMiKQpwbG90KHJlcy5sb25nLCB0eXBlPSdsJykKYGBgCgoK0JDQstGC0L7QutC+0LLQsNGA0LjQsNGG0LjQvtC90L3QsNGPINGE0YPQvdC60YbQuNGPCmBgYHtyLCBmaWcuaGVpZ2h0PTUsIGZpZy53aWR0aD0xMH0KYWNmKHJlcy5sb25nLCBsYWcubWF4ID0gNTApCmBgYArQqNGD0Lwg0L/QvtGF0L7QtiDQvdCwINCx0LXQu9GL0LkuCgojI9Ca0L7RgNC90Lgg0KXQnwoKTWluLW5vcm0g0JvQoNCkCgoqICRQX2kkIC0tINGB0YLQvtC70LHRhtGLINGC0YDQsNC10LrRgtC+0YDQvdC+0Lkg0LzQsNGC0YDQuNGG0YsKKiAkXHVuZGVybGluZXtQfV97aX0kIC0tINCy0LXQutGC0L7RgCAkUF9pJCDQsdC10Lcg0L/QvtGB0LvQtdC00L3QtdC5INC60L7QvtGA0LTQuNC90LDRgtGLCiogJFxwaV9pJCAtLSDQv9C+0YHQu9C10LTQvdGP0Y8g0LrQvtC+0YDQtNC40L3QsNGC0LAgJFBfaSQKCtCa0L7RjdGE0YTQuNGG0LjQtdC90YLRiyBtaW4tbm9ybSDQm9Cg0KQ6CgokXG1hdGhjYWx7Un0gPSBcZnJhY3sxfXsxLVxudV4yfVxzdW1cbGltaXRzX3tpPTF9XntkfXtccGlfaSBcdW5kZXJsaW5le1B9X3tpfX0kLCDQs9C00LUgJFxudV4yID0gXHBpXzFeMiArIOKApiArIFxwaV9kXjIkCgokeF97aSArIGR9ID0gXHN1bVxsaW1pdHNfe2sgPSAxfV5kYV9reF97aSArIGQgLSBrfSQsICRhX2QgXG5lcSAwJCAtLSDQvNC40L3QuNC80LDQu9GM0L3QsNGPINCb0KDQpCAKCiRQKFxtdSkgPSBcbXVeZCAtIFxzdW1cbGltaXRzX3trID0gMX1eZGFfa1xtdV57ZCAtIGt9JCAtLSDRhdCw0YDQsNC60YLQtdGA0LjRgdGC0LjRh9C10YHQutC40Lkg0L/QvtC70LjQvdC+0Lwg0JvQoNCkCgokXHtcbXVfalx9X3tqID0gMX1ecCQgLS0g0LrQvtGA0L3QuCDRhS7Qvy4g0LrRgNCw0YLQvdC+0YHRgtC4ICRrX2okLCAkXHN1bSBrX2ogPSBkJCwg0YLQvtCz0LTQsCAKCiR4X24gPSBcc3VtXGxpbWl0c197bSA9IDF9XnAoXHN1bVxsaW1pdHNfe2ogPSAwfV57a20gLSAxfSBDX3ttX2p9IG5eailcbXVfbV5uJAoKbWluLW5vcm0g0JvQoNCkINC4INC10LUg0LrQvtGA0L3QuCAo0L/RgNC10LTQv9C+0LvQsNCz0LDQtdC8LCDRh9GC0L4g0YDQsNC90LMg0YDRj9C00LAgOCkKYGBge3J9CmxyIDwtIGxycihzc2EubG9uZywgZ3JvdXBzID0gbGlzdCgxOjgpKQpwbG90KGxyKQpyIDwtIHJvb3RzKGxyKQpgYGAKCtCl0L7RgtC40Lwg0L/QvtGB0YLRgNC+0LjRgtGMINGE0L7RgNC80YPQu9GDINC00LvRjyDRgdC40LPQvdCw0LvQsCDRgNGP0LTQsCDRgSDRiNGD0LzQvtC8LgoK0JLQt9GP0LIg0LHQvtC70YzRiNC+0LUg0L7QutC90L4g0Lgg0L/QvtGB0YLRgNC+0LjQsiBtaW4tbm9ybSDQm9Cg0KQsINC90LDQudC00LXQvCDQvNC90L7Qs9C+INC60L7RgNC90LXQuSDRhS7Qvy4KCtCa0LDQuiDQstGL0LHRgNCw0YLRjCDQuNC3INC90LjRhSDRgtC1IHIg0LrQvtGA0L3QtdC5LCDRh9GC0L4g0L7Qv9GA0LXQtNC10LvRj9GO0YIg0YHRgtGA0YPQutGC0YPRgNGDINGB0LjQs9C90LDQu9CwPwoK0J3QsNC50LTQtdC8INGB0LjQs9C90LDQu9GM0L3Ri9C1INC60L7RgNC90LgsINCy0L7RgdC/0L7Qu9GM0LfQvtCy0LDQstGI0LjRgdGMINGD0YLQstC10YDQttC00LXQvdC40LXQvCwg0YfRgtC+INGDIG1pbi1ub3JtINCb0KDQpCDQstGB0LUg0LvQuNGI0L3QuNC1INC60L7RgNC90Lgg0L/QviDQvNC+0LTRg9C70Y4g0LzQtdC90YzRiNC1INC10LTQuNC90LjRhtGLLgpgYGB7cn0KbW9kcyA8LSBNb2QocikKcHJpbnQoclttb2RzID49IDFdKQpgYGAKCtCf0LXRgNC10LLQtdGA0L3QtdC8INGA0Y/QtApgYGB7cn0KbHIuYmFjayA8LSBscnIoc3NhLmxvbmcsIGdyb3VwcyA9IGxpc3QoMTo4KSwgcmV2ZXJzZSA9IFRSVUUpCnIuYmFjayA8LSByb290cyhsci5iYWNrKQptb2RzLmJhY2sgPC0gTW9kKHIuYmFjaykKcHJpbnQoci5iYWNrW21vZHMuYmFjayA+PSAxXSkKYGBgCtCc0L7QtNGD0LvQuCDQs9C70LDQstC90YvRhSDQutC+0YDQvdC10LkKYGBge3J9Cm1haW4ucm9vdHMgPC0gYyhyW01vZChyKSA+PSAxXSwgMS9yLmJhY2tbTW9kKHIuYmFjaykgPj0gMV0pCnByaW50KE1vZChtYWluLnJvb3RzKSkKYGBgCgrQodC+0L7RgtCy0LXRgtGB0YLQstGD0Y7RidC40LUg0L/QtdGA0LjQvtC00YsKYGBge3J9CnByaW50KDIqcGkvQXJnKG1haW4ucm9vdHMpKQpgYGAKCmBgYHtyLCBmaWcuaGVpZ2h0PSA1LCBmaWcud2lkdGg9NX0KcGxvdChtYWluLnJvb3RzLCB4bGltID0gYygtMSwxKSwgeWxpbSA9IGMoLTEsMSksIGFzcCA9IDEsIHhsYWIgPSAiUmUiLCB5bGFiID0gIkltIikKZHJhdy5jaXJjbGUoMCwwLDEsYm9yZGVyID0gJ3JlZCcpCmBgYAoK0J3QsNGI0LvQvtGB0Ywg0YLQvtC70YzQutC+IDYg0YHQuNCz0L3QsNC70YzQvdGL0YUg0LrQvtGA0L3QtdC5LCDQsCDQtNC+0LvQttC90L4g0LHRi9GC0YwgOC4KCtCf0L7Qv9GA0L7QsdGD0LXQvCDQtNGA0YPQs9C+0Lkg0YHQv9C+0YHQvtCxOiAKCtCh0L7RgdGC0LDQstC40Lwg0YHQuNGB0YLQtdC80YMg0Lgg0L3QsNC50LTQtdC8INC60L7RjdGE0YTQuNGG0LjQtdC90YLRiyDQv9C+INCc0J3QmgpgYGB7cn0KY29tcGxleC5MUyA8LSBmdW5jdGlvbihzZXJpZXMsIHNlcmllcy5yb290cyl7CiAgIFggPC0gbWFwcGx5KEZVTiA9IGZ1bmN0aW9uKHJvb3Qpe3Jvb3ReKDE6bGVuZ3RoKHNlcmllcykpfSwgc2VyaWVzLnJvb3RzKQogICBZIDwtIGNiaW5kKHNlcmllcykKICAgbGlzdChjb2VmID0gc29sdmUoQ29uaih0KFgpKSUqJVgpICUqJSBDb25qKHQoWCkpICUqJSBZLAogICAgICAgIFggPSBYKQp9CmNvZWZmcy5lc3RpbWF0ZXMgPC0gY29tcGxleC5MUyhsb25nLnJlY29uc3RydWN0ZWQkdHJlbmQgKyBsb25nLnJlY29uc3RydWN0ZWQkcGVyaW9kaWMsIHIpCmBgYAoK0JLQvtGB0L/QvtC70YzQt9GD0LXQvNGB0Y8g0YLQtdC8LCDRh9GC0L4g0L/QtdGA0LXQtCDRgdC40LPQvdCw0LvRjNC90YvQvNC4INC60L7RgNC90Y/QvNC4INC00L7Qu9C20L3RiyDRgdGC0L7Rj9GC0Ywg0LzQsNC60YHQuNC80LDQu9GM0L3Ri9C1INC60L7RjdGE0YTQuNGG0LjQtdC90YLRiwpgYGB7cn0KaWR4LnJvb3RzIDwtb3JkZXIoTW9kKGNvZWZmcy5lc3RpbWF0ZXMkY29lZiksIGRlY3JlYXNpbmcgPSBUUlVFKVsxOjhdCm1haW4ucm9vdHM8LXJbaWR4LnJvb3RzXQpyZXMuY29lZmZzIDwtIGNvZWZmcy5lc3RpbWF0ZXMkY29lZltpZHgucm9vdHNdCmBgYAoKCtCc0L7QtNGD0LvQuCDQs9C70LDQstC90YvRhSDQutC+0YDQvdC10LkKYGBge3J9CnByaW50KE1vZChtYWluLnJvb3RzKSkKYGBgCgrQodC+0L7RgtCy0LXRgtGB0YLQstGD0Y7RidC40LUg0L/QtdGA0LjQvtC00YsKYGBge3J9CnByaW50KDIqcGkvQXJnKG1haW4ucm9vdHMpKQpgYGAKCgpgYGB7ciwgZmlnLmhlaWdodD0gNSwgZmlnLndpZHRoPTV9CnBsb3QobWFpbi5yb290cywgeGxpbSA9IGMoLTEsMSksIHlsaW0gPSBjKC0xLDEpLCBhc3AgPSAxLCB4bGFiID0gIlJlIiwgeWxhYiA9ICJJbSIpCmRyYXcuY2lyY2xlKDAsMCwxLGJvcmRlciA9ICdyZWQnKQpgYGAKCmBgYHtyfQpyZWxhdGlvbiA8LSBmdW5jdGlvbihuKXsKICByYmluZChyZXMuY29lZmZzKSAlKiUgdChtYXBwbHkoRlVOID0gZnVuY3Rpb24ocm9vdCl7cm9vdF5ufSwgbWFpbi5yb290cykpCn0KYGBgCgoKYGBge3J9CnBsb3QobG9uZy5yZWNvbnN0cnVjdGVkJHRyZW5kICsgbG9uZy5yZWNvbnN0cnVjdGVkJHBlcmlvZGljLCB0eXBlID0gJ2wnLCB5bGFiID0gInNlcmllcyIpCmxpbmVzKHggPSAxOjEwMDAsIHkgPSBSZShyZWxhdGlvbigxOjEwMDApKSwgY29sID0gJ3JlZCcpCmBgYAoKI1Nob3J0IHNlcmllcwoKYGBge3J9CnBsb3Qoc2hvcnQsIHR5cGU9J2wnKQpgYGAKYGBge3J9CnNwZWMucGdyYW0oc2hvcnQsIGRldHJlbmQgPSBUUlVFLCBmYXN0ID0gRkFMU0UsIGxvZz0nbm8nLCB0YXBlcj0wLCB4YXh0ID0gJ24nKQpsIDwtIHNlcSgwLCAwLjUsIDAuMDUpCmF4aXMoMSwgYXQgPSBsLCBsYWJlbHMgPSBsKQpgYGAK0J7QttC40LTQsNC10LwsINGH0YLQviDRgNCw0L3QsyDRgNGP0LTQsCDQutCw0Log0LzQuNC90LjQvNGD0LwgNCAo0YLRgNC10L3QtCArINGB0LjQvdGD0YEpLgoKRGVjb21wb3NpdGlvbgpgYGB7cn0Kc2hvcnQuc3NhIDwtIHNzYShzaG9ydCwga2luZD0nMWQtc3NhJykKYGBgCgrQodC+0LHRgdGC0LLQtdC90L3Ri9C1INGH0LjRgdC70LAKYGBge3J9CnBsb3Qoc2hvcnQuc3NhKQpgYGAKCgoKCtCh0L7QsdGB0YLQstC10L3QvdGL0LUg0LLQtdC60YLQvtGA0LA6CmBgYHtyLCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD04fQpwbG90KHNob3J0LnNzYSwgdHlwZT0ndmVjdG9ycycsIGlkeCA9IDE6MjApCmBgYAogCgpgYGB7ciwgZmlnLndpZHRoPSA4LCBmaWcuaGVpZ2h0PSA4fQpwbG90KHNob3J0LnNzYSwgdHlwZT0ncGFpcmVkJywgaWR4PSBjKDE6MjApKQpgYGAKCmBgYHtyfQpwYXJlc3RpbWF0ZShzaG9ydC5zc2EsIGdyb3VwcyA9IGxpc3QoMzo0LCA1OjYsIDc6OCwgMTE6MTIsIDEzOjE0KSkKYGBgCgoKIApgYGB7ciwgZmlnLndpZHRoPTUsIGZpZy5oZWlnaHQ9NX0KcGxvdCh3Y29yKHNob3J0LnNzYSwgZ3JvdXBzID0gYXMubGlzdCgxOjIwKSkpCmBgYAoKYGBge3IsIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTh9CnNob3J0LnJlY29uc3RydWN0ZWQgPC0gcmVjb25zdHJ1Y3Qoc2hvcnQuc3NhLCBsaXN0KAogIHRyZW5kID0gYygxLCAyKSwKICBwZXJpb2RpYyA9IGMoMzo4LDExOjE0KSkpCnJlcy5zaG9ydCA8LSByZXNpZHVhbHMoc2hvcnQucmVjb25zdHJ1Y3RlZCkKcGFyKG1mcm93PWMoNCwxKSkKcGxvdChzaG9ydCwgdHlwZSA9ICdsJykKcGxvdChzaG9ydC5yZWNvbnN0cnVjdGVkJHRyZW5kLCB0eXBlPSdsJywgeWxhYiA9ICJ0cmVuZCIpCnBsb3Qoc2hvcnQucmVjb25zdHJ1Y3RlZCRwZXJpb2RpYywgdHlwZT0nbCcsIHlsYWIgPSAicGVyaW9kaWMiKQpwbG90KHJlcy5zaG9ydCwgdHlwZT0nbCcpCmBgYApgYGB7ciwgZmlnLmhlaWdodD01LCBmaWcud2lkdGg9MTB9CmFjZihyZXMuc2hvcnQsIGxhZy5tYXggPSA1MCkKYGBgCgojI1Byb2plY3Rpb24gU1NBCgrQlNCy0L7QudC90L7QtSDRhtC10L3RgtGA0LjRgNC+0LLQsNC90LjQtQoKJFxtYXRoY2Fse0F9KFxtYXRoYmZ7WH0pID0gW1xtYXRoY2Fse0V9XzEoXG1hdGhiZntYfSkgOiBcbGRvdHMgOiBcbWF0aGNhbHtFfV8xKFxtYXRoYmZ7WH0pXSQsINCz0LTQtSAkXG1hdGhjYWx7RX1fMShcbWF0aGJme1h9KSQgLS0g0LLQtdC60YLQvtGAINC40Lcg0YHRgNC10LTQvdC40YUg0L/QviDRgdGC0YDQvtC60LDQvAoKJFxtYXRoY2Fse0J9KFxtYXRoYmZ7WH0pID0gW1xtYXRoY2Fse0V9X3sxMn0oXG1hdGhiZntYfSkgOiBcbGRvdHMgOiBcbWF0aGNhbHtFfV97MTJ9KFxtYXRoYmZ7WH0pXSQsINCz0LTQtSAkXG1hdGhjYWx7RX1fezEyfShcbWF0aGJme1h9KSQgLS0g0LLQtdC60YLQvtGALCDQsiDQutC+0YLQvtGA0L7QvCBqLdCw0Y8g0LrQvtC80L/QvtC90LXQvdGC0LAg0YDQsNCy0L3QsCDRgdGA0LXQtNC90LXQvNGDINC60L7QvNC/0L7QvdC10L3RgiAkWF9qXnsoYyl9ID0gWF9pIC0gXG1hdGhjYWx7RX1fMShcbWF0aGJme1h9KSQuCgrQn9GA0Lgg0LTQstC+0LnQvdC+0Lwg0YbQtdC90YLRgNC40YDQvtCy0LDQvdC40Lgg0L/RgNC40LzQtdC90Y/QtdC8IFNWRCDQuiDQvNCw0YLRgNC40YbQtSAkXG1hdGhiZntBfSA9IFxtYXRoY2Fse0F9KFxtYXRoYmZ7WH0pICsgXG1hdGhjYWx7Qn0oXG1hdGhiZntYfSkkCgrQn9C+0LvRg9GH0LjQvCDRgNCw0LfQu9C+0LbQtdC90LjQtSAkXG1hdGhiZntYfSA9IFxtYXRoYmZ7QX0gKyBcc3VtXGxpbWl0c197aSA9IDF9XmRcc3FydHtcbGFtYmRhX2l9VV9pVl9pXlxtYXRocm17VH0kLCDQs9C00LUgJChcbGFtYmRhX2ksIFVfaSwgVl9pKSQg0YHQvtC+0YLQstC10YLRgdGC0LLRg9GO0YIgJFNeKiA9IChcbWF0aGJme1h9IC0gXG1hdGhiZntBfSkoXG1hdGhiZntYfSAtIFxtYXRoYmZ7QX0pXlxtYXRocm17VH0kLgoKCtCi0LDQuiDQutCw0Log0LjRgdGF0L7QtNC90YvQuSDRgtGA0LXQvdC0INC70LjQvdC10LnQvdGL0LksINC00LLQvtC50L3QvtC1INGG0LXQvdGC0YDQuNGA0L7QstCw0L3QuNC1INC/0L7QvNC+0LbQtdGCINC+0YLQtNC10LvQuNGC0Ywg0LvQuNC90LXQudC90YPRjiDRh9Cw0YHRgtGMINC+0YIg0LrQvtC70LXQsdCw0L3QuNC5ICjQu9C40L3QtdC50L3QsNGPINGH0LDRgdGC0Ywg0L/QvtC/0LDQtNC10YIg0LIgJFxtYXRoYmZ7QX0kKS4KCmBgYHtyfQpzaG9ydC5wcm9qZWN0aW9uLnNzYSA8LSBzc2EoeCA9IHNob3J0LCBjb2x1bW4ucHJvamVjdG9yID0gJ2NlbnRlcmluZycsIHJvdy5wcm9qZWN0b3IgPSAnY2VudGVyaW5nJykKYGBgCgpgYGB7ciwgZmlnLmhlaWdodD01LCBmaWcud2lkdGg9MTB9CnBsb3Qoc2hvcnQucHJvamVjdGlvbi5zc2EpCnBsb3Qoc2hvcnQucHJvamVjdGlvbi5zc2EsIHR5cGU9J3ZlY3RvcnMnLCBpZHggPSAxOjIwKQpgYGAKCtCf0L4g0LLQuNC00YMg0YHQvtCx0YHRgtCy0LXQvdC90YvRhSDQstC10LrRgtC+0YDQvtCyINCy0LjQtNC90L4sINGH0YLQviDRgtGA0LXQvdC0INC+0YLQtNC10LvQuNC70YHRjyDQu9GD0YfRiNC1LgoKYGBge3J9CnBsb3Qoc2hvcnQucHJvamVjdGlvbi5zc2EsIHR5cGU9J3BhaXJlZCcsIGlkeD0gYygxOjIwKSkKcGFyZXN0aW1hdGUoc2hvcnQucHJvamVjdGlvbi5zc2EsIGdyb3VwcyA9IGxpc3QoMzo0LCA1OjYsIDc6OCwgMTE6MTIsIDEzOjE0KSwgbWV0aG9kID0iZXNwcml0LWxzIikKYGBgCgoKYGBge3IsIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTh9CnNob3J0LnJlY29uc3RydWN0ZWQgPC0gcmVjb25zdHJ1Y3Qoc2hvcnQucHJvamVjdGlvbi5zc2EsIGxpc3QoCiAgdHJlbmQgPSBjKDEsIDIpLAogIHBlcmlvZGljID0gYygzOjgsMTE6MTQpKSkKcmVzLnByb2plY3Rpb24gPC0gcmVzaWR1YWxzKHNob3J0LnJlY29uc3RydWN0ZWQpCnBhcihtZnJvdz1jKDQsMSkpCnBsb3Qoc2hvcnQsIHR5cGUgPSAnbCcpCnBsb3Qoc2hvcnQucmVjb25zdHJ1Y3RlZCR0cmVuZCwgdHlwZT0nbCcsIHlsYWIgPSAidHJlbmQiKQpwbG90KHNob3J0LnJlY29uc3RydWN0ZWQkcGVyaW9kaWMsIHR5cGU9J2wnLCB5bGFiID0gInBlcmlvZGljIikKcGxvdChyZXMucHJvamVjdGlvbiwgdHlwZT0nbCcpCmBgYAoKYGBge3IsIGZpZy5oZWlnaHQ9NSwgZmlnLndpZHRoPTEwfQphY2YocmVzLnByb2plY3Rpb24sIGxhZy5tYXggPSA1MCkKYGBgCtCh0YLQsNC70L4g0L3QtdC80L3QvtCz0L4g0LvRg9GH0YjQtSwg0L3QviDQstGB0LUt0YLQsNC60Lgg0YfRgtC+LdGC0L4g0L7RgdGC0LDQu9C+0YHRjC4KCiNUb2VwbGl0eiBTU0EgdnMgQmFzaWMgU1NBCgrQlNC70Y8g0LrQvtGA0L7RgtC60LjRhSDRgNGP0LTQvtCyLCDQutC+0YLQvtGA0YvQtSDQv9GA0LXQtNC/0L7Qu9Cw0LPQsNGO0YLRgdGPINGB0YLQsNGG0LjQvtC90LDRgNC90YvQvNC4INGA0LXQutC+0LzQtdC90LTRg9C10YLRgdGPINC30LDQvNC10L3Rj9GC0Ywg0LzQsNGC0YDQuNGG0YMgJFxtYXRoYmZ7U30gPSBcbWF0aGJme1h9XG1hdGhiZntYfV5cbWF0aHJte1R9JCDQvdCwINCw0LLRgtC+0LrQvtCy0LDRgNC40LDRhtC40L7QvdC90YPRjiDQvNCw0YLRgNC40YbRgyAkXHdpZGV0aWxkZXtcbWF0aGJme0N9fSQg0L3QsCDRjdGC0LDQv9C1INGA0LDQt9C70L7QttC10L3QuNGPCgoKJFx3aWRldGlsZGV7Y31fe2lqfSA9IFxmcmFjezF9e04gLSB8aSAtIGp8fSBcc3VtXGxpbWl0c197bSA9IDF9XntOIC0gfGkgLSBqfH0geF9tIHhfe20gKyB8aSAtIGp8fSQsICQxIFxsZXEgaSwgaiBcbGVxIEwkLgoK0JfQsNC80LXRh9Cw0L3QuNC1OgoK0J/QvtC70YPRh9C10L3QvdC+0LUg0YDQsNC70L7QttC10L3QuNC1ICRcbWF0aGJie1h9ID0gXHN1bVxsaW1pdHNfe2kgPSAxfV5MXHNpZ21hX2lQX2lRX2leXG1hdGhybXtUfSQsINCz0LTQtSAkUF9pJCAtLSDRgS7Qsi4gJFx3aWRldGlsZGV7XG1hdGhiZntDfX0kLCDQvtCx0YDQsNC30YPRjtGCINC+0YDRgtC+0L3QvtGA0LzQuNGA0L7QstCw0L3QvdGL0Lkg0LHQsNC30LjRgSDQsiAkXG1hdGhiYntSfSQsICRRX2kgPSBcZnJhY3tcbWF0aGJie1h9XlxtYXRocm17VH1QX2l9e1x8XG1hdGhiYntYfV5cbWF0aHJte1R9UF9pXHx9JC4g0K3RgtC+INGA0LDQt9C70L7QttC10L3QuNC1INC90LUg0Y/QstC70Y/QtdGC0YHRjyDRgdC40L3Qs9GD0LvRj9GA0L3Ri9C8INGA0LDQt9C70L7QttC10L3QuNC10LwsICRcc2lnbWFfaSA9IFx8XG1hdGhiYntYfV5cbWF0aHJte1R9UF9pXHwkINCy0L7QvtCx0YnQtSDQs9C+0LLQvtGA0Y8g0L3QtSDRgdC+0LHRgdGC0LLQtdC90L3Ri9C1INGH0LjRgdC70LAgJFx3aWRldGlsZGV7XG1hdGhiZntDfX0kLgoKCtCf0YDQuNC80LXRgDog0YDRj9C0ICR4X24gPSBlXntcYWxwaGEgbn0gY29zKDJccGkgbi83KSArIFxlcHNpbG9uX24kCmBgYHtyfQpzZXQuc2VlZCgxMDApCmVwcyA8LSBybm9ybSgxMDApCmFscGhhIDwtIHNlcSgwLjAwMDEsIDAuMDEsIDAuMDAwMSkKeCA8LSBtYXBwbHkoRlVOID0gZnVuY3Rpb24oYSkge2V4cChhICogKDE6MTAwKSkgKiBjb3MoMipwaSooMToxMDApLzcpICsgZXBzfSwgYWxwaGEpCgpiYXNpYyA8LSBhcHBseSh4LCAyLCBGVU4gPSBmdW5jdGlvbihzZXJpZXMpewogIHMgPC0gc3NhKHNlcmllcykKICByZWMgPC0gcmVjb25zdHJ1Y3QocywgZ3JvdXBzID0gbGlzdCh0cmVuZCA9IGMoMSwgMikpKQogIHBlciA8LSBzZXJpZXMgLSBlcHMKICBtc2UgPC0gc3VtKChyZWMkdHJlbmQgLSBwZXIpXjIpL2xlbmd0aChwZXIpCn0pCgp0ZW9wbGl0eiA8LSBhcHBseSh4LCAyLCBGVU4gPSBmdW5jdGlvbihzZXJpZXMpewogIHMgPC0gc3NhKHNlcmllcywga2luZCA9ICJ0b2VwbGl0ei1zc2EiKQogIHJlYyA8LSByZWNvbnN0cnVjdChzLCBncm91cHMgPSBsaXN0KHRyZW5kID0gYygxLCAyKSkpCiAgcGVyIDwtIHNlcmllcyAtIGVwcwogIG1zZSA8LSBzdW0oKHJlYyR0cmVuZCAtIHBlcileMikvbGVuZ3RoKHBlcikKfSkKYGBgCmBgYHtyfQpwbG90KHkgPSB0ZW9wbGl0eiwgeCA9IGFscGhhLCB0eXBlID0gImwiLCB5bGFiID0gIk1TRSIsIHhsYWIgPSAnYWxwaGEnLCBtYWluID0gIlRlb3BsaXR6IHZzIEJhc2ljIFNTQSIpCmxpbmVzKHkgPSBiYXNpYywgIHggPSBhbHBoYSwgIGNvbCA9ICdyZWQnKQpsZWdlbmQoInRvcGxlZnQiLCBjKCJUZW9wbGl0eiIsICJCYXNpYyIpLCBsdHk9YygxLDEpLCBsd2Q9YygyLjUsMi41KSxjb2w9YygiYmxhY2siLCJyZWQiKSkKYGBgCgoj0J/QvtGB0LvQtdC00L7QstCw0YLQtdC70YzQvdGL0Lkg0LDQvdCw0LvQuNC3INGA0LXQsNC70YzQvdC+0LPQviDRgNGP0LTQsApgYGB7cn0KdWsgPC0gcmVhZC5jc3YoIlVLLmNzdiIsIHNlcCA9ICcsJywgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFKQp1ayA8LSB0cyh1ayRFWFBFTkQsIHN0YXJ0ID0gYygxOTgwLCAxKSwgZnJlcXVlbmN5ID0gMTIpCgpkZi51ayA8LSBkYXRhLmZyYW1lKHNlcS5EYXRlKGZyb20gPSBhcy5EYXRlKCIxOTgwLTAxLTAxIiksIHRvID0gYXMuRGF0ZSgiMjAxNi0xMi0wMSIpLCBieSA9ICJtb250aCIpLCB1aykKY29sbmFtZXMoZGYudWspIDwtIGMoIkRBVEUiLCAiRVhQIikKaGVhZCh1aywgMjQpCmBgYApgYGB7cn0KcGxvdCh1aykKYGBgCgoK0J/QtdGA0LjQvtC00L7Qs9GA0LDQvNC80LAg0YDRj9C00LAKYGBge3J9CnNwZWMucGdyYW0odWssIGRldHJlbmQgPSBUUlVFLCBmYXN0ID0gRkFMU0UsIGxvZz0nbm8nLCB4YXh0ID0gJ24nKQpheGlzKDEsIGF0ID0gYygwLDEsMiwzLDQsNSw2KSwgbGFiZWxzID0gYygnMCcsICcxLzEyJywgJzIvMTInLCAnMy8xMicsICc0LzEyJywgJzUvMTInLCAnNi8xMicpKQpgYGAKCiMj0KHQs9C70LDQttC40LLQsNC90LjQtQoKKiDQotGA0LXQvdC0INGB0LvQvtC20L3QvtC5INGE0L7RgNC80YssINCy0L7Qt9C80L7QttC90L4sINC90LUg0L7Qv9C40YHRi9Cy0LDQtdGC0YHRjyDRgNGP0LTQvtC8INC60L7QvdC10YfQvdC+0Lkg0YDQsNC30LzQtdGA0L3QvtGB0YLQuAoqINCV0YHQu9C4INCy0YvQsdC10YDQtdC8INCx0L7Qu9GM0YjQvtC1INC+0LrQvdC+LCDQutC+0LzQv9C+0L3QtdC90YLRiyDRgtGA0LXQvdC00LAg0YHQvNC10YjQsNGO0YLRgdGPINGBINC/0LXRgNC40L7QtNC40YfQtdGB0LrQuNC80LgKKiDQktC+0LfRjNC80LXQvCDQvNCw0LvQtdC90YzQutC+0LUg0L7QutC90L46INGF0L7RgNC+0YjQviDQstGL0LTQtdC70LjQvCDRgtGA0LXQvdC0LCDQvdC+INGB0LzQtdGI0LDRjtGC0YHRjyDQvtGB0YLQsNC70YzQvdGL0LUg0LrQvtC80L/QvtC90LXQvdGC0YsKKiDQoNC10YjQtdC90LjQtTog0YHQvdCw0YfQsNC70LAg0LLRi9C00LXQu9C40Lwg0YLRgNC10L3QtCDRgSDQvNCw0LvQtdC90YzQutC40Lwg0L7QutC90L7QvCwg0L/QvtGC0L7QvCDQv9GA0LjQvNC10L3QuNC8IFNTQSDRgSDQsdC+0LvRjNGI0LjQvCDQvtC60L3QvtC8INC6INC+0YHRgtCw0YLQutGDLgoK0JLRi9Cx0LjRgNCw0LXQvCDQvdC10LHQvtC70YzRiNGD0Y4g0LTQu9C40L3RgyDQvtC60L3QsCDQutGA0LDRgtC90YPRjiDQv9C10YDQuNC+0LTRgyDRgdC10LfQvtC90L3QvtC5INC60L7QvNC/0L7QvdC10L3RgtGLLCBMID0gMjQuCmBgYHtyfQp1ay5zc2EgPC0gc3NhKHVrLCBMID0gMjQpCmBgYAoK0JLQutC70LDQtNGLCmBgYHtyfQpwbG90KHVrLnNzYSkKYGBgCgrQktC40LTQvdC+LCDRh9GC0L4g0YHQvtCx0YHRgtCy0LXQvdC90YvQtSDRh9C40YHQu9CwINC/0LXRgNC40L7QtNC40YfQtdGB0LrQuNGFINC60L7QvNC/0L7QvdC10L3RgiDQsdC70LjQt9C60LjQtS4g0KHQutC+0YDQtdC1INCy0YHQtdCz0L4g0Y3RgtC4INC60L7QvNC/0L7QvdC10L3RgtGLINGB0LzQtdGI0LDRjtGC0YHRjyAo0L/RgNC+0LHQu9C10LzQsCDRgSDRgdC40LvRjNC90L7QuSDRgNCw0LfQtNC10LvQuNC80L7RgdGC0YzRjikuCgoK0KHQvtCx0YHRgtCy0LXQvdC90YvQtSDQstC10LrRgtC+0YDQsApgYGB7cn0KcGxvdCh1ay5zc2EsIHR5cGU9InZlY3RvcnMiLCBpZHg9MToxMikKcGxvdCh1ay5zc2EsIHR5cGU9InBhaXJlZCIsIGlkeD0xOjExKQpgYGAKIyPQktC+0YHRgdGC0LDQvdC+0LLQu9C10L3QvdGL0LUg0L/QviDRjdC70LXQvNC10L3RgtCw0YDQvdGL0Lwg0LrQvtC80L/QvtC90LXQvdGC0LDQvApgYGB7cn0KcGxvdCh1ay5zc2EsIHR5cGUgPSdzZXJpZXMnLCBncm91cHMgPSBhcy5saXN0KDE6MTIpKQpgYGAK0J/QtdGA0LLQsNGPINGN0LvQtdC80LXQvdGC0LDRgNC90LDRjyDQutC+0LzQv9C+0L3QtdC90YLQsCDRgdC+0L7RgtCy0LXRgtGB0YLQstGD0LXRgiDRgtGA0LXQvdC00YMsINC00LDQu9GM0YjQtSDQuNC00YPRgiDQv9C10YDQuNC+0LTQuNC60LguCgojI9CS0YvQtNC10LvQtdC90LjQtSDRgtGA0LXQvdC00LAKCmBgYHtyfQp1ay50cmVuZCA8LSByZWNvbnN0cnVjdCh1ay5zc2EsIGdyb3VwcyA9IGxpc3QoMSkpCnBsb3QodWspCmxpbmVzKHVrLnRyZW5kJEYxLCBjb2wgPSAncmVkJykKdWsuZGV0cmVuZGVkIDwtIHJlc2lkdWFscyh1ay50cmVuZCkKYGBgCtCf0LXRgNC40L7QtNC+0LPRgNCw0LzQvNCwINC+0YHRgtCw0YLQutCwCmBgYHtyfQpzcGVjLnBncmFtKHVrLmRldHJlbmRlZCwgZGV0cmVuZCA9IEZBTFNFLCBmYXN0ID0gRkFMU0UsIGxvZz0nbm8nLCB4YXh0ID0gJ24nKQpheGlzKDEsIGF0ID0gYygwLDEsMiwzLDQsNSw2KSwgbGFiZWxzID0gYygnMCcsICcxLzEyJywgJzIvMTInLCAnMy8xMicsICc0LzEyJywgJzUvMTInLCAnNi8xMicpKQpgYGAK0J7QttC40LTQsNC10LwsINGH0YLQviDQtNCw0LvRjNGI0LUg0LHRg9C00LXRgiDQtNC+0YHRgtCw0YLQvtGH0L3QviDQstGL0LTQtdC70LjRgtGMIDkg0LrQvtC80L/QvtC90LXQvdGCICjRgdC40L3Rg9GBINGBINC/0LXRgNC40L7QtNC+0LwgMiDQuNC80LXQtdGCINGA0LDQvdCzIDEpLgoKIyPQodC10LfQvtC90L3QvtGB0YLRjAoK0JLQvtC30YzQvNC10Lwg0LzQsNC60YHQuNC80LDQu9GM0L3QvtC1ICRMIFxsZXEgTi8yJCDQutGA0LDRgtC90L7QtSAxMiwg0YIu0LUuIDIxNiAo0LTQu9C40L3QsCDRgNGP0LTQsCA0NDQpLgoKYGBge3J9CnVrLmRldHJlbmRlZC5zc2EgPC0gc3NhKHVrLmRldHJlbmRlZCwgTD0yMTYpCnBsb3QodWsuZGV0cmVuZGVkLnNzYSkKYGBgCtCS0LjQtNC90L4g0YHRgtGD0L/QtdC90YzQutC4LCDQutC+0YLQvtGA0YvQtSwg0LLQvtC30LzQvtC20L3Qviwg0YHQvtC+0YLQstC10YLRgdGC0LLRg9GO0YIg0YHQuNC90YPRgdC+0LjQtNCw0LwuCgoKYGBge3IsIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTh9CnBsb3QodWsuZGV0cmVuZGVkLnNzYSwgdHlwZSA9ICJwYWlyZWQiLCBpZHggPSAxOjMwLCBwbG90LmNvbnRyaWIgPSBGQUxTRSkKYGBgCtCX0LDQvNC10YLQvdGLINC60L7QvNC/0L7QvdC10L3RgtGLLCDRgdC+0L7RgtCy0LXRgtGB0YLQstGD0Y7RidC40LUg0L/QtdGA0LjQvtC00LDQvCAxMiwgNiwgNCDQuCAyLjQuCgoK0JrQvtC80L/QvtC90LXQvdGC0LAsINGB0L7QvtGC0LLQtdGC0YHRgtCy0YPRjtGJ0LDRjyDQv9C10YDQuNC+0LTRgyAyLgpgYGB7cn0KcGxvdCh1ay5kZXRyZW5kZWQuc3NhLCB0eXBlID0gInZlY3RvcnMiLCBpZHggPSA5LCBwbG90LmNvbnRyaWIgPSBGQUxTRSkKYGBgCgrQn9GA0L7QstC10YDQuNC8CmBgYHtyfQpwYXJlc3RpbWF0ZSh1ay5kZXRyZW5kZWQuc3NhLCBncm91cHMgPSBsaXN0KDE6OSksIG1ldGhvZCA9ICJlc3ByaXQtbHMiKQpgYGAKCgpXLdC60L7RgNGA0LXQu9GP0YbQuNC+0L3QvdCw0Y8g0LzQsNGC0YDQuNGG0LAKCmBgYHtyLCBmaWcud2lkdGg9NSwgZmlnLmhlaWdodD01fQpwbG90KHdjb3IodWsuZGV0cmVuZGVkLnNzYSwgZ3JvdXBzID0gYXMubGlzdCgxOjIwKSkpCmBgYAoKYGBge3J9CnVrLnNlYXNvbmFsaXR5IDwtIHJlY29uc3RydWN0KHVrLmRldHJlbmRlZC5zc2EsIGdyb3VwcyA9IGxpc3QoMTo5KSkKcmVzMSA8LSByZXNpZHVhbHModWsuc2Vhc29uYWxpdHkpCmBgYApgYGB7ciwgZmlnLmhlaWdodD0xMCwgZmlnLndpZHRoPTh9CnBhcihtZnJvdz1jKDQsMSkpCnBsb3QodWssIHR5cGUgPSAnbCcsIHlsYWI9J09yaWdpbmFsJykKcGxvdCh1ay50cmVuZCRGMSwgdHlwZT0nbCcsIHlsYWI9J1RyZW5kJykKcGxvdCh1ay5zZWFzb25hbGl0eSRGMSwgdHlwZT0nbCcsIHlsYWIgPSAnU2Vhc29uYWwgQ29tcG9uZW50JykKcGxvdChyZXMxLCB0eXBlPSdsJywgeWxhYj0nUmVzaWR1YWxzJykKYGBgCtCSINC+0YHRgtCw0YLQutC1INC+0YHRgtCw0LvRgdGPINGC0YDQtdC90LQuCgoKYGBge3J9CmFjZihyZXMxKQpzcGVjLnBncmFtKHJlczEsIGRldHJlbmQgPSBGQUxTRSwgZmFzdCA9IEZBTFNFLCBsb2c9J25vJywgeGF4dCA9ICduJykKYXhpcygxLCBhdCA9IGMoMCwxLDIsMyw0LDUsNiksIGxhYmVscyA9IGMoJzAnLCAnMS8xMicsICcyLzEyJywgJzMvMTInLCAnNC8xMicsICc1LzEyJywgJzYvMTInKSkKYGBgCgojI9Ce0YbQtdC90LrQsCDQtNC40YHQv9C10YDRgdC40Lgg0YjRg9C80LAKYGBge3J9CnNpZ21hLm4uc3FyIDwtIHNzYShyZXMxXjIsIEwgPSAzMCkKc2lnbWEubiA8LSBzcXJ0KHJlY29uc3RydWN0KHNpZ21hLm4uc3FyLCBncm91cHMgPSBsaXN0KDEpKSRGMSkKcGxvdChyZXMxLCB0eXBlPSdsJykKbGluZXMoc2lnbWEubiwgdHlwZSA9ICdsJywgY29sPSdibHVlJykKbGluZXMoLXNpZ21hLm4sIHR5cGU9J2wnLCBjb2w9J2JsdWUnKQpgYGAKCiNGb3JlY2FzdGluZwoK0KDQsNGB0YHQvNC+0YLRgNC40Lwg0YLQvtGCINC20LUg0YHQsNC80YvQuSDRgNGP0LQsINC90L4g0LHQtdC3INC/0L7RgdC70LXQtNC90LjRhSDRiNC10YHRgtC4INC70LXRgi4KYGBge3J9CnVrLnRyYWluIDwtIGhlYWQodWssIC03MikKcGxvdCh1ay50cmFpbikKdWsudHJhaW4uc3NhIDwtIHNzYSh1ay50cmFpbiwgTCA9IDI0KQp1ay50cmFpbi50cmVuZCA8LSByZWNvbnN0cnVjdCh1ay50cmFpbi5zc2EsIGdyb3VwcyA9IDEpCnVrLnRyYWluLmRldHJlbmRlZCA8LSByZXNpZHVhbHModWsudHJhaW4udHJlbmQpCnVrLnRyYWluLmRldHJlbmRlZC5zc2EgPC0gc3NhKHVrLnRyYWluLmRldHJlbmRlZCwgTCA9IDE4MCkKdWsudHJhaW4uc2Vhc29uYWxpdHkgPC0gcmVjb25zdHJ1Y3QodWsudHJhaW4uZGV0cmVuZGVkLnNzYSwgZ3JvdXBzID0gbGlzdCgxOjkpKQpgYGAKCgojI1ItZm9yZWNhc3RpbmcKCtCf0YDQvtC00L7Qu9C20LDQtdC8INGA0Y/QtCDRgSDQv9C+0LzQvtGJ0YzRjiBtaW4tbm9ybSBMUlIuCmBgYHtyfQp1ay50cmVuZC5mb3JlY2FzdCA8LSBwcmVkaWN0KHVrLnRyYWluLnNzYSwgbWV0aG9kID0gInJlY3VycmVudCIsIGxlbiA9IDcyLCBncm91cHMgPSAxKQp1ay5zZWFzb25hbGl0eS5mb3JlY2FzdCA8LSBwcmVkaWN0KHVrLnRyYWluLmRldHJlbmRlZC5zc2EsIG1ldGhvZCA9ICJyZWN1cnJlbnQiLCBsZW4gPSA3MiwgZ3JvdXBzID0gbGlzdCgxOjkpKQpwbG90KHVrLCB4bGltID0gYygyMDAwLCAyMDIwKSkKbGluZXModWsudHJlbmQuZm9yZWNhc3QgKyB1ay5zZWFzb25hbGl0eS5mb3JlY2FzdCwgY29sID0gJ3JlZCcpCmBgYApNU0UKYGBge3J9CnN1bSgodGFpbCh1aywgNzIpIC0gKHVrLnRyZW5kLmZvcmVjYXN0ICsgdWsuc2Vhc29uYWxpdHkuZm9yZWNhc3QpKV4yKS83MgpgYGAKCiMjVi1mb3JlY2FzdGluZwoKYGBge3J9CnVrLnRyZW5kLmZvcmVjYXN0IDwtIHByZWRpY3QodWsudHJhaW4uc3NhLCBtZXRob2QgPSAidmVjdG9yIiwgbGVuID0gNzIsIGdyb3VwcyA9IDEpCnVrLnNlYXNvbmFsaXR5LmZvcmVjYXN0IDwtIHByZWRpY3QodWsudHJhaW4uZGV0cmVuZGVkLnNzYSwgbWV0aG9kID0gInZlY3RvciIsIGxlbiA9IDcyLCBncm91cHMgPSBsaXN0KDE6OSkpCnBsb3QodWssIHhsaW0gPSBjKDIwMDAsIDIwMjApKQpsaW5lcyh1ay50cmVuZC5mb3JlY2FzdCArIHVrLnNlYXNvbmFsaXR5LmZvcmVjYXN0LCBjb2wgPSAncmVkJykKYGBgCgpNU0UKYGBge3J9CnN1bSgodGFpbCh1aywgNzIpIC0gKHVrLnRyZW5kLmZvcmVjYXN0ICsgdWsuc2Vhc29uYWxpdHkuZm9yZWNhc3QpKV4yKS83MgpgYGAKCiMj0JTQvtCy0LXRgNC40YLQtdC70YzQvdGL0LUg0LjQvdGC0LXRgNCy0LDQu9GLCgpCb290c3RyYXA6CgoqINCS0YvQtNC10LvRj9C10Lwg0YHQuNCz0L3QsNC7INGBINC/0L7QvNC+0YnRjNGOIFNTQQoqINCe0YbQtdC90LjQstCw0LXQvCDQtNC40YHQv9C10YDRgdC40Y4g0L7RgdGC0LDRgtC60LAg0Lgg0LzQvdC+0LPQviDRgNCw0Lcg0LzQvtC00LXQu9C40YDRg9C10Lwg0LPQsNGD0YHRgdC+0LLRgdC60LjQuSDRiNGD0LwKKiDQktGL0LTQtdC70Y/QtdC8INGB0LjQs9C90LDQuyDQuNC3INC+0YbQtdC90LXQvdC90L7Qs9C+INGB0LjQs9C90LDQu9CwICsg0LzQvtC00LXQu9C40YDQvtCy0LDQvdC90L7Qs9C+INGI0YPQvNCwCiog0J/QvtC70YPRh9C40Lwg0LzQvdC+0LPQviDQvtGG0LXQvdC+0Log0YHQuNCz0L3QsNC70LAKKiDQodGC0YDQvtC40Lwg0L/RgNC+0LTQvtC70LbQtdC90LjRjwoqINCe0YLQsdGA0LDRgdGL0LLQsNC10LwgJCgxIC0gXGdhbW1hKS8yJCDRgSDQutC+0L3RhtC+0LIKCmBgYHtyfQp1ay50cmVuZC5mb3JlY2FzdCA8LSBwcmVkaWN0KHVrLnRyYWluLnNzYSwgbWV0aG9kID0gImJvb3RzdHJhcC1yZWN1cnJlbnQiLCBsZW4gPSA3MiwgZ3JvdXBzID0gMSkKdWsuc2Vhc29uYWxpdHkuZm9yZWNhc3QgPC0gcHJlZGljdCh1ay50cmFpbi5kZXRyZW5kZWQuc3NhLCBtZXRob2QgPSAiYm9vdHN0cmFwLXJlY3VycmVudCIsIGxlbiA9IDcyLCBncm91cHMgPSBsaXN0KDE6OSkpCnBsb3QodWssIHhsaW0gPSBjKDIwMTAsIDIwMTgpKQpsaW5lcyh1ay50cmVuZC5mb3JlY2FzdFssMV0gKyB1ay5zZWFzb25hbGl0eS5mb3JlY2FzdFssMV0sIGNvbCA9ICdyZWQnKQpsaW5lcyh1ay50cmVuZC5mb3JlY2FzdFssMl0gKyB1ay5zZWFzb25hbGl0eS5mb3JlY2FzdFssMl0sIGNvbCA9ICdibHVlJyxsdHk9ImRhc2hlZCIpCmxpbmVzKHVrLnRyZW5kLmZvcmVjYXN0WywzXSArIHVrLnNlYXNvbmFsaXR5LmZvcmVjYXN0WywzXSwgY29sID0gJ2JsdWUnLGx0eT0iZGFzaGVkIikKYGBgCgoj0JfQsNC/0L7Qu9C90LXQvdC40LUg0L/RgNC+0L/Rg9GB0LrQvtCyCgrQoNCw0YHRgdC80L7RgtGA0LjQvCDRgNGP0LQKYGBge3J9CnVrLmhlYWQgPC0gaGVhZCh1aywgLSAxMjApCnBsb3QodWsuaGVhZCkKYGBgCgoK0JTQvtCx0LDQstC40Lwg0L/RgNC+0L/Rg9GB0LrQuCDQsiDRgNGP0LQKYGBge3J9CnVrLm5hIDwtIHVrLmhlYWQKbWlzc2VkIDwtIHVrLmhlYWRbMTIxOjE4MF0KdWsubmFbMTIxOjE4MF0gPSBOQQpwbG90KHVrLm5hLCB0eXBlID0gJ2wnKQpgYGAKCiMj0JDQu9Cz0L7RgNC40YLQvAoKU3Vic3Bhc2UtYmFzZWQgbWV0aG9kOgoKKiDQndCwINGN0YLQsNC/0LUg0LTQtdC60L7QvNC/0L7Qt9C40YbQuNC4LCDQuNGB0LrQu9GO0YfQsNC10Lwg0LLQtdC60YLQvtGA0LAg0LLQu9C+0LbQtdC90LjRjywg0YHQvtC00LXRgNC20LDRidC40LUg0L/RgNC+0L/Rg9GJ0LXQvdC90YvQtSDRjdC70LXQvNC10L3RgtGLCiog0JjQtyDQvtGB0YLQsNCy0YjQuNGF0YHRjyDQstC10LrRgtC+0YDQvtCyINGB0L7RgdGC0LDQstC70Y/QtdC8INGC0YDQsNC10LrRgtC+0YDQvdGD0Y4g0LzQsNGC0YDQuNGG0YMKKiBTVkQKKiDQn9GA0L7QtdC60YbQuNGPINC90LAgJFxtYXRoY2Fse0x9X3IkIAoqINCf0YDQvtC10LrRhtC40Y8g0L3QtdC/0L7Qu9C90YvRhSDQstC10LrRgtC+0YDQvtCyINC90LAgJFxtYXRoY2Fse0x9X3IkLiAKKiAi0L/RgNC10LTRgdC60LDQt9Cw0L3QuNC1INCy0L4g0LLQvdGD0YLRgNGMIiDRgSDQv9C+0LzQvtGJ0YzRjiDQu9GA0YQsCtC/0L7RgdGC0YDQvtC10L3QvdC+0Lkg0L/QviDQuNC80LXRjtGJ0LjQvNGB0Y8g0LTQsNC90L3Ri9C8LiDQn9GA0LXQtNGB0LrQsNC30YvQstCw0LXQvCDRgdC70LXQstCwINC4INGB0L/RgNCw0LLQsCDRgSDQu9C40L3QtdC50L3QviDRg9Cx0YvQstCw0Y7RidC40LzQuCDQstC10YHQsNC80LgsCtCwINC/0L7RgtC+0Lwg0YPRgdGA0LXQtNC90Y/QtdC8Ciog0JTQuNCw0LPQvtC90LDQu9GM0L3QvtC1INGD0YHRgNC10LTQvdC10L3QuNC1CgrQmNGC0LXRgNCw0YLQuNCy0L3Ri9C5INC80LXRgtC+0LQ6IAoKKiDQl9Cw0L/QvtC70L3Rj9C10Lwg0L/RgNC+0L/Rg9GB0LrQuCwg0L3QsNC/0YDQuNC80LXRgCwg0YHRgNC10LTQvdC40LwKKiByINC4IEwg0YTQuNC60YHQuNGA0L7QstCw0L3RiyAo0L3QsNC/0YDQuNC80LXRgCDQstGL0LHRgNCw0LvQuCDRgSDQv9C+0LzQvtGJ0YzRjiBjdikKKiDQn9GA0LjQvNC10L3QuNC8IFNTQSwg0LLRgdGC0LDQstC40Lwg0LjQvdGC0LXRgNC10YHRg9GO0YnRg9GOINC90LDRgSDRh9Cw0YHRgtGMINCyINC40YHRhdC+0LTQvdGL0Lkg0YDRj9C0LCDRgdC90L7QstCwINC/0YDQuNC80LXQvdC40LwgU1NBINC4INGC0LDQuiDQtNCw0LvQtdC1CgrQnNC40L3Rg9GBOiDQtNC70Y8g0L/RgNC+0LPQvdC+0LfQsCDQvdC1INCz0L7QtNC40YLRgdGPLgoKYGBge3J9CnVrLm5hLnNzYSA8LSBzc2EodWsubmEsIEwgPSA3MikKYGBgCgojI9Cf0YDQtdC00YHQutCw0LfQsNC90LjQtSDQstC+INCy0L3Rg9GC0YDRjApgYGB7cn0KZyA8LSBnYXBmaWxsKHVrLm5hLnNzYSwgZ3JvdXBzID0gbGlzdCgxOjgpKQpwbG90KHVuY2xhc3ModWsuaGVhZCksIHR5cGUgPSAnbCcpCmxpbmVzKHkgPSB1bmNsYXNzKGdbMTIxOjE4MF0pLCB4ID0gMTIxOjE4MCwgY29sID0gJ3JlZCcsIGx0eSA9IDIpCmBgYApNU0UKYGBge3J9CnN1bSgoZ1sxMjE6MTgwXSAtIG1pc3NlZCleMikvNjAKYGBgCgojI9CY0YLQtdGA0LDRgtC40LLQvdGL0Lkg0LzQtdGC0L7QtAoKCmBgYHtyfQpnLml0IDwtIGlnYXBmaWxsKHVrLm5hLnNzYSwgZ3JvdXBzID0gbGlzdCgxOjgpKQpwbG90KHVuY2xhc3ModWsuaGVhZCksIHR5cGUgPSAnbCcpCmxpbmVzKHkgPSB1bmNsYXNzKGcuaXRbMTIxOjE4MF0pLCB4ID0gMTIxOjE4MCwgY29sID0gJ3JlZCcsIGx0eSA9IDIpCmBgYAoKTVNFCmBgYHtyfQpzdW0oKGcuaXRbMTIxOjE4MF0gLSBtaXNzZWQpXjIpLzYwCmBgYArQmNGC0LXRgNCw0YLQuNCy0L3Ri9C5INC80LXRgtC+0LQg0L7QutCw0LfQsNC70YHRjyDRgtC+0YfQvdC10LUuCgoKIzJELVNTQSDQtNC70Y8g0YDQsNC30LvQvtC20LXQvdC40Y8g0LjQt9C+0LHRgNCw0LbQtdC90LjRjwoK0KDQsNGB0YHQvNC+0YLRgNC40Lwg0YTQvtGC0L7Qs9GA0LDRhNC40Y4g0YHQv9GD0YLQvdC40LrQsCDQodCw0YLRg9GA0L3QsCwg0JTQuNC+0L3RiyAoW9CY0YHRgtC+0YfQvdC40LpdKGh0dHBzOi8vd3d3Lm5hc2EuZ292L2ltYWdlLWZlYXR1cmUvanBsL3BpYTIwNTIxL3JheXMtb2YtY3JldXNhKSkuCgrQn9GA0L7Rh9C40YLQsNC70Lgg0LrQsNGA0YLQuNC90LrRgwpgYGB7ciwgZmlnLndpZHRoPTUsIGZpZy5oZWlnaHQ9NX0KZGlvbmUgPC0gcmVhZEpQRUcoIkRpb25lLmpwZyIpCmltYWdlKGRpb25lLCBjb2wgPSBncmV5KHNlcSgwLCAxLCBsZW5ndGggPSAyNTYpKSkKYGBgCgrQlNC+0LHQsNCy0LjQvCDRiNGD0LwKYGBge3IsIGZpZy53aWR0aD01LCBmaWcuaGVpZ2h0PTV9CnNldC5zZWVkKDEwMCkKbm9pc2UubWF0cml4IDwtIGFwcGx5KGRpb25lLCAyLCBmdW5jdGlvbih4KXtybm9ybShsZW5ndGgoeCksIHNkID0gMC4zKX0pCmRpb25lLm5vaXNlZCA8LSBkaW9uZSArIG5vaXNlLm1hdHJpeAppbWFnZShkaW9uZS5ub2lzZWQsIGNvbCA9IGdyZXkoc2VxKDAsIDEsIGxlbmd0aCA9IDI1NikpKQpgYGAKCgoyZC1zc2EKYGBge3J9CmRpb25lLnNzYSA8LSBzc2EoZGlvbmUubm9pc2VkLCBraW5kID0gIjJkLXNzYSIsIEwgPSBjKDI1LDI1KSkKYGBgCgrQodC+0LHRgdGC0LLQtdC90L3Ri9C1INCy0LXQutGC0L7RgNCwCmBgYHtyfQpwbG90KGRpb25lLnNzYSwgdHlwZSA9ICJ2ZWN0b3JzIiwgaWR4ID0gMTozMCwgY3V0cyA9IDI1NSwgbGF5b3V0ID0gYygxMCwgMiksIHBsb3QuY29udHJpYiA9IEZBTFNFKQpgYGAKCnct0LrQvtGA0YDQtdC70Y/RhtC40L7QvdC90LDRjyDQvNCw0YLRgNC40YbQsApgYGB7cn0KcGxvdCh3Y29yKGRpb25lLnNzYSwgZ3JvdXBzID0gMTozMCksc2NhbGVzID0gbGlzdChhdCA9IHNlcSgxMCwgMzAsIDUpKSkKYGBgCgoK0KHQs9GA0YPQv9C/0LjRgNGD0LXQvCDQutC+0LzQv9C+0L3QtdC90YLRiyDRgSDRh9Cw0YHRgtC+0YLQsNC80Lgg0L/QvtGF0L7QttC10LPQviDQstC40LTQsApgYGB7cn0KZGlvbmUucmVjb25zdHJ1Y3RlZCA8LSByZWNvbnN0cnVjdChkaW9uZS5zc2EsIGdyb3VwcyA9IGxpc3QoSTEgPSBjKDE6MTMpLCBJMiA9IGMoMTQ6MTUpLCBJMyA9IGMoMTY6MTcpKSkKYGBgCgoK0J3QsNC60L7Qv9C70LXQvdC90YvQtSDRgdGD0LzQvNGLINC60L7QvNC/0L7QvdC10L3RggpgYGB7cn0KcGxvdChkaW9uZS5yZWNvbnN0cnVjdGVkLCBjdXRzID0gMjU1LCBsYXlvdXQgPSBjKDUsIDEpLCBwYXIuc3RyaXAudGV4dCA9IGxpc3QoY2V4ID0gMC43NSksIHR5cGUgPSAiY3Vtc3VtIiwgYXQgPSAiZnJlZSIpCmBgYAoKIyNTaGFwZWQgU1NBCgrQo9Cx0LXRgNC10Lwg0YfQtdGA0L3Ri9C5INGE0L7QvQpgYGB7cn0KZGlvbmUud2l0aG91dC5ibGFjayA8LSBhcHBseShkaW9uZSwgMiwgRlVOID0gZnVuY3Rpb24oY29sKXsKICBzYXBwbHkoY29sLCBGVU4gPSBmdW5jdGlvbihlbGVtZW50KXsKICAgIGlmKGVsZW1lbnQgPD0gMC4xKXsKICAgICAgcmV0dXJuKE5BKQogICAgfSBlbHNlewogICAgICByZXR1cm4oZWxlbWVudCkKICAgIH0KICB9KQp9KQpgYGAKCmBgYHtyLCBmaWcud2lkdGg9NSwgZmlnLmhlaWdodD01fQppbWFnZShkaW9uZS53aXRob3V0LmJsYWNrLCBjb2wgPSBncmV5KHNlcSgwLCAxLCBsZW5ndGggPSAyNTYpKSkKYGBgCtCU0L7QsdCw0LLQuNC8INGI0YPQvApgYGB7ciwgZmlnLndpZHRoPTUsIGZpZy5oZWlnaHQ9NX0KZGlvbmUud2l0aG91dC5ibGFjay5ub2lzZWQgPC0gZGlvbmUud2l0aG91dC5ibGFjayArIG5vaXNlLm1hdHJpeAppbWFnZShkaW9uZS53aXRob3V0LmJsYWNrLm5vaXNlZCwgY29sID0gZ3JleShzZXEoMCwgMSwgbGVuZ3RoID0gMjU2KSkpCmBgYAoK0J/QvtC/0YDQvtCx0YPQtdC8INC40LfQvNC10L3QuNGC0Ywg0YTQvtGA0LzRgyDQvtC60L3QsCDQvdCwINC60YDRg9CzLgpgYGB7cn0KZGlvbmUuc3NhLnNoYXBlZCA8LSBzc2EoZGlvbmUud2l0aG91dC5ibGFjay5ub2lzZWQsIGtpbmQgPSAiMmQtc3NhIiwgd21hc2sgPSBjaXJjbGUoMjApKQpgYGAKCmBgYHtyfQpwbG90KGRpb25lLnNzYS5zaGFwZWQsIHR5cGUgPSAidmVjdG9ycyIsIGlkeCA9IDE6MzAsIGN1dHMgPSAyNTUsIGxheW91dCA9IGMoMTAsIDIpLCBwbG90LmNvbnRyaWIgPSBGQUxTRSkKYGBgCgp3LdC60L7RgNGA0LXQu9GP0YbQuNC+0L3QvdCw0Y8g0LzQsNGC0YDQuNGG0LAKYGBge3J9CnBsb3Qod2NvcihkaW9uZS5zc2Euc2hhcGVkLCBncm91cHMgPSAxOjMwKSxzY2FsZXMgPSBsaXN0KGF0ID0gc2VxKDEwLCAzMCwgNSkpKQpgYGAK0J/QviDQvNCw0YLRgNC40YbQtSDQvNC+0LbQvdC+INGB0LTQtdC70LDRgtGMINCy0YvQstC+0LQg0L4g0YLQvtC8LCDRh9GC0L4g0L/RgNC40LHQu9C40LfQuNGC0LXQu9GM0L3QviAxMCDQv9C10YDQstGL0YUg0LrQvtC80L/QvtC90LXQvdGCINC+0YLQvdC+0YHRj9GC0YHRjyDQuiDRgdC40LPQvdCw0LvRgywg0LAg0L7RgdGC0LDQu9GM0L3QvtC1INGN0YLQviDRiNGD0LwuCgrQodCz0YDRg9C/0L/QuNGA0YPQtdC8INC60L7QvNC/0L7QvdC10L3RgtGLINGBINGH0LDRgdGC0L7RgtCw0LzQuCDQv9C+0YXQvtC20LXQs9C+INCy0LjQtNCwCmBgYHtyfQpkaW9uZS5yZWNvbnN0cnVjdGVkLnNoYXBlZCA8LSByZWNvbnN0cnVjdChkaW9uZS5zc2Euc2hhcGVkLCBncm91cHMgPSBsaXN0KEkxID0gYygxOjYpLCBJMiA9IGMoNzoxMiksIEkzID0gYygxMzoxOSkpKQpgYGAKCgrQndCw0LrQvtC/0LvQtdC90L3Ri9C1INGB0YPQvNC80Ysg0LrQvtC80L/QvtC90LXQvdGCCmBgYHtyfQpwbG90KGRpb25lLnJlY29uc3RydWN0ZWQuc2hhcGVkLCBjdXRzID0gMjU1LCBsYXlvdXQgPSBjKDUsIDEpLCBwYXIuc3RyaXAudGV4dCA9IGxpc3QoY2V4ID0gMC43NSksIHR5cGUgPSAiY3Vtc3VtIiwgYXQgPSAiZnJlZSIpCmBgYArQndCwINCy0LjQtCwg0LjRgdGF0L7QtNC90LDRjyDQutCw0YDRgtC40L3QutCwINC70YPRh9GI0LUg0L7RgtC00LXQu9C40LvQsNGB0Ywg0L7RgiDRiNGD0LzQsCDQsiDRgdC70YPRh9Cw0LUgc2hhcGVkIFNTQS4KCgojRXhwb25lbnRpYWwgU21vb3RoaW5nCgooRVMgdnMgU1NBIHZzIEFSSU1BKQoKYGBge3J9CmVzLmZpdCA8LSBlcyh1ay50cmFpbiwgaCA9IDcyKQpgYGAKCk1TRQpgYGB7cn0Kc3VtKCh0YWlsKHVrLDcyKSAtIGVzLmZpdCRmb3JlY2FzdCleMikvNzIKYGBgCgrQnNC+0LTQtdC70YwKYGBge3J9CmVzLmZpdCRmb3JtdWxhCmBgYAoKCmBgYHtyfQp1ay50cmVuZC5mb3JlY2FzdCA8LSBwcmVkaWN0KHVrLnRyYWluLnNzYSwgbWV0aG9kID0gInJlY3VycmVudCIsIGxlbiA9IDcyLCBncm91cHMgPSAxKQp1ay5zZWFzb25hbGl0eS5mb3JlY2FzdCA8LSBwcmVkaWN0KHVrLnRyYWluLmRldHJlbmRlZC5zc2EsIG1ldGhvZCA9ICJyZWN1cnJlbnQiLCBsZW4gPSA3MiwgZ3JvdXBzID0gbGlzdCgxOjkpKQpwbG90KHVrLCB4bGltID0gYygyMDEwLCAyMDE4KSkKbGluZXModWsudHJlbmQuZm9yZWNhc3QgKyB1ay5zZWFzb25hbGl0eS5mb3JlY2FzdCwgY29sID0gJ3JlZCcpCmBgYApgYGB7cn0Kc3VtKCh0YWlsKHVrLDcyKSAtICh1ay50cmVuZC5mb3JlY2FzdCArIHVrLnNlYXNvbmFsaXR5LmZvcmVjYXN0KSleMikvNzIKYGBgCgoKYGBge3J9CmF1dG8uZml0LnVrIDwtIGF1dG8uYXJpbWEodWsudHJhaW4sIHRyYWNlID0gVFJVRSwgc3RlcHdpc2UgPSBGQUxTRSwgYWxsb3dkcmlmdCA9IEZBTFNFKQphcmltYS5wcmVkaWN0aW9uLnVrIDwtIHByZWRpY3QoYXV0by5maXQudWssIDcyKQpwbG90KHVrLCB4bGltID0gYygyMDEwLCAyMDE4KSkKbGluZXMoYXJpbWEucHJlZGljdGlvbi51ayRwcmVkLCBjb2wgPSAncmVkJykKbGluZXMoYXJpbWEucHJlZGljdGlvbi51ayRwcmVkICsgYXJpbWEucHJlZGljdGlvbi51ayRzZSwgbHR5ID0gJ2Rhc2hlZCcsIGNvbCA9ICdibHVlJykKbGluZXMoYXJpbWEucHJlZGljdGlvbi51ayRwcmVkIC0gYXJpbWEucHJlZGljdGlvbi51ayRzZSwgbHR5ID0gJ2Rhc2hlZCcsIGNvbCA9ICdibHVlJykKYGBgCgpNU0UKYGBge3J9CnN1bSgodGFpbCh1ayw3MikgLSBhcmltYS5wcmVkaWN0aW9uLnVrJHByZWQpXjIpLzcyCmBgYAoK